Analysis of Samsung S22 and Apple iPhone 13

The Smartphone Market

The global smartphone market has experienced multiple market leaders over the past few years. The only two major brands that remained over the years were Apple and Samsung. Those two brands are compared regularly and are competing over the market share. While Samsung was the market leader in the first three quarters in 2021. In September 2021, Apple released its new iPhone model with the generation 13 and gained market share, taking over the market leader position. In February 2022, Samsung also released the new model in its Galaxy series. Those two phones are the flagships in the current smartphone market.

Source: IDC. (2022). Global smartphone market share from 4th quarter 2009 to 4th quarter 2021 (by vendor). Statista. Statista Inc.. Accessed: April 14, 2022.

Samsung Galaxy S22

The Samsung Galaxy S series is the high-end model produced and sold by Samsung, a South Korean multinational electronics company. The S series has 13 generations. Together with the Galaxy Z and Galaxy Note (discontinued) series, the S series serves as flagship models (Wikipedia, n.d.). Samsung S series uses the open source operating system Android (Samsung).

In February 2022 the model S22 was released in three variants: S22, S22 Plus (also: S22+) and S22 Ultra (Wikipedia, n.d.). It comes in the colours that are shown in the picture below, namely: phantom white, burgundy, phantom black and green (Samsung). Also the S22 Ultra variant comes with an so-called “S Pen” which lets the user write on their phone and can be recharged within the phone (Samsung).

Samsung advertises the S22 series with the following features:

  • "The phone that makes everyday epic

  • Nightography camera

  • A battery that lasts the day and beyond

  • Our fastest chip ever"

(Source: Samsung)

Picture Source

Apple iPhone 13

The Apple iPhone series is the only smartphone series produced and sold by Apple Inc, an US-American multinational technology company (Wikipedia).

The generation 13 was released in September 2021 in three variants: iPhone 13, iPhone 13 mini, iPhone 13 Pro, iPhone 13 Pro Max and iPhone SE. The regular variant and mini can be bought in the colours: green, pink, blue, midnight, starlight, red. The variants Pro and Pro Max are available in: alpine green, silver, gold, graphite, sierra blue. The iPhone SE is available in: midnight, starlight, red (Apple).

Apple advertises the iPhone Pro with the following features:

  • "A dramatically more powerful camera system.

  • A display so responsive, every interaction feels new again.

  • The world’s fastest smartphone chip.

  • Exceptional durability.

  • And a huge leap in battery life." (Samsung)

Picture Source

Comparison of Features

Samsung S22 Apple iPhone 13
Starting Price $799 $799
Screen size 6.1 inches (2340 x 1080) 6.1 inches (2532 x 1170)
Refresh rate 48Hz-120Hz adaptive 60Hz
CPU Snapdragon 8 Gen 1 (US); Exynos 2200 (K) A15 Bionic
RAM 8GB 4GB (based on teardowns)
Storage 128GB, 256GB 128GB, 256GB, 512GB
Rear cameras 50MP wide (f/1.8); 12MP ultrawide (f/2.2); 10MP telephoto (f/2.4) with 3x optical zoom 12MP main (f/1.6), 12MP ultrawide (f/2.4)
Front camera 10MP (f/2.2) 12MP (f/2.2)
Battery size 3,700 mAh 3,227 mAh (based on teardowns)
Battery life (Hrs:Mins) 7:51 10:33
Charging speeds 25W wired, 15W wireless 20W wired; 15W wireless
Size 5.7 x 2.8 x 0.3 inches 5.8 x 2.8 x 0.3 inches
Weight 5.9 ounces 6.14 ounces
Colors Black, white, green, pink gold Black, white, blue, pink, red, green

Source: https://www.tomsguide.com/face-off/samsung-galaxy-s22-vs-iphone-13

Objectives of our Research

  • Identification of the strengths and weaknesses of the competitors which can help to identify a gap in a market and enhancing the own business strategy.

  • Identification of suggestions to customers about the products based on other customers’ opinions

Methodology of our Research

Twitter Analysis

Data Extraction and Cleaning

Samsung S22

We decided to extract data from Twitter with the keywords “Samsung S22” and the hashtag “#samsungs22” from 31.03.2022 - 08.04.2022 as we do not have a premium license to get access to the full timeline of tweets on the TwitterAPI.

We excluded from our query the users ShopeeID, _arllee and all retweets for the keywords “Samsung S22” because there were multiple thousands of tweets about a competition to win a Samsung mobile phone which caused a lot of duplicated data.

As well, we identified nine users which were creating advertising spam and non-valuable tweets that we had to exclude: “whitestonedome”, “FromKorea5”, “dome_glass”, “Whitestone_DE”, “whitestone_UK”, “jp_whitestone”, “Whitestone__FR”, “WhitestoneJapan”, “WhitestoneEU”.

In total we could gather 3846 tweets.

Our initial data frame has 17 attributes. You can find the meaning of each of the attributes here on the Twitter Developer Platform.

In the following code we checked that the data.frame was correctly formatted:

Apple iPhone 13

We extracted data for the search terms “iPhone 13” excluding retweets and the hashtag “#iphone13” from the TwitterAPI. Similarly, to the Samsung S22 we had to exclude certain users which were advertising (“whitestonedome”, “FromKorea5”, “domeglassapple”) and competitions to win an iPhone when retweeting or copy-pasting a specific text (“Join the event to win an iPhone 13!”). Also, we had a high number of tweets which were randomly posting brand names, e.g. “rolex iphone” in one tweet.

In total we could gather 8369 tweets.

Our initial data frame has 17 attributes. You can find the meaning of each of the attributes here on the Twitter Developer Platform.

In the following code we checked that the data.frame was correctly formatted:

'data.frame':   8369 obs. of  18 variables:
 $ X.1          : int  1 2 3 4 5 6 7 8 9 10 ...
 $ X            : int  1 2 3 4 5 6 7 8 9 10 ...
 $ text         : chr  "Apple iPhone 13 Pro Max, Graphite, 256GB -...  - https://t.co/WN9QahDmcf #Deals #iPhone_deals #ukdealsonline ht"| __truncated__ "@person_pikin1 @Olamideofficial @kusssman Simple!!\n\n13+11=24\n\nIt’s iPhone 24 pro max" "@GetLocoNow iam an eSports player and I have Android devices it's lagg too much. I hope I'll win iPhone 13 for "| __truncated__ "iphone 13 blue or starlight or pink? which one is better huh?" ...
 $ favorited    : logi  FALSE FALSE FALSE FALSE FALSE FALSE ...
 $ favoriteCount: int  0 0 0 1 0 0 0 0 0 2 ...
 $ replyToSN    : chr  NA "person_pikin1" "GetLocoNow" NA ...
 $ created      : chr  "2022-04-08 12:34:13" "2022-04-08 12:34:09" "2022-04-08 12:31:41" "2022-04-08 12:31:09" ...
 $ truncated    : logi  FALSE FALSE TRUE FALSE TRUE FALSE ...
 $ replyToSID   : num  NA 1.51e+18 NA NA 1.51e+18 ...
 $ id           : num  1.51e+18 1.51e+18 1.51e+18 1.51e+18 1.51e+18 ...
 $ replyToUID   : num  NA 1.23e+18 9.40e+17 NA 5.42e+08 ...
 $ statusSource : chr  "<a href=\"https://www.rssground.com\" rel=\"nofollow\">RSS Ground</a>" "<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter for iPhone</a>" "<a href=\"http://twitter.com/download/android\" rel=\"nofollow\">Twitter for Android</a>" "<a href=\"https://mobile.twitter.com\" rel=\"nofollow\">Twitter Web App</a>" ...
 $ screenName   : chr  "ukdealsonline" "c_r_u_i_s_e_" "PrinceAlioth" "mmuhdnoahh" ...
 $ retweetCount : int  2 0 0 0 0 0 0 0 0 0 ...
 $ isRetweet    : logi  FALSE FALSE FALSE FALSE FALSE FALSE ...
 $ retweeted    : logi  FALSE FALSE FALSE FALSE FALSE FALSE ...
 $ longitude    : num  NA NA NA NA NA NA NA NA NA NA ...
 $ latitude     : num  NA NA NA NA NA NA NA NA NA NA ...

How Many Users Were Posting How Many Tweets in the Dataset?

While there were only 3846 tweets from users about the Samsung S22, there were 2.17 times more tweets about the Apple iPhone 13 during the period considered.

On 3 out of 9 days Samsung S22 had more tweets than iPhone 13. On the other days Apple exceeded the number of tweets extremely. Surprisingly, the number of tweets and users per day for the Samsung S22 remains constant while there are only a few tweets about the iPhone 13 in the first 3 days and a high volume of tweets from 3nd April until 7th April 2022. There was not only more tweets but also a larger group of users posting about iPhone 13. We could not identify a specific reason for this phenomenon because the last official Apple event was in March 2022 and not in the time period we tested.

There is no similar indicator from Google Trends or other sources. The search terms iPhone 13, Samsung S22, Apple and Samsung are relatively constant over time as you can see from the image below (Screenshot from Google Trends). It can be noted that Apple is more likely to be looked up than Samsung as well as the iPhone 13 is more popular on Google Search than Samsung S22. This gives us a first impression that the iPhone 13 model receives in general more attention.

There are more tweets than users which indicates that some users usually post more than one tweet. We calculated a ratio for this: avg_tweets_per_user = tweets per day / users per day.

It is interesting though there were less conversation about Apple in the first three days, there were statistically more people involved, so it seems to be a conversation between a smaller group of users. We see the same for Samsung S22 between 4th April to 6th April 2022.

Wordcloud

Data Preprocessing

We decided to preprocess the data based on the following steps:

  • All text was converted to lower case, e.g. Hello to hello.

  • All contractions were converted to the longer form, e.g. don’t to do not

  • All common internet slang was converted to formal English, e.g. TGIF to Thanks God it is Friday

  • Hashtags (#) were removed

  • Word elongation was replaced to the usual word form, e.g. heeeeey to hey

  • All non-ASCII characters were replaced with equivalent or removed, © to (C)

  • White space within the string is reduced to one white space

  • White space at the start and end of the string was removed

  • “RT”, implicating that its a retweet was removed

  • all links were removed based on the start of “http”

  • all @username were removed

  • punctuation were removed

  • stop words were removed based on the RegEx approach

Results

wordcloud(word_s, min.freq = 60, max.words = 40, random.order = FALSE, color= pal)

Samsung S22 users mentioned Samsung, Galaxy (which is the series of the S22) and Ultra (which is a specific model). The Ultra model is comparable to the iPhone 13 Pro.

Also iPhone, Pro, Max, Note & OnePlus are mentioned which are other comparable smartphones in the market.

Other words that are often mentioned belong to specifications that users talked about:

  • android, update, security

  • camera, pixel, video

  • features

  • mediatek

  • screen

  • amp

  • case

wordcloud(word_a, min.freq = 60, max.words = 40, random.order = FALSE, color= pal)

We can identify that Apple iPhone is mentioned in the variants Pro, Mini and Max. Pro seems to be the most important one, then Max and then the Mini.

As with the Samsung S22, also here it is mentioned with “Ultra”, “Galaxy” and “Samsung”.

The specifications of the phone that users talked about were:

  • pixel, camera

  • battery, amp

  • price

  • case

  • green

For iPhone 13, we can notice that some adjectives and verbs were mentioned a lot:

available, buy, win, free, still, now, good, better, best, like, will, get, want, need, can

We will identify topics further during our analysis using LDA Topic Modelling.

Insights

Both models are mentioned with their camera and pixel but only Samsung has the word “video” mentioned a lot. We identified in our pre-research about the phones that both companies advertise their smartphones based on the camera. None of both mentions about positive abilities in the video recording in their main advertisement.

For Samsung S22 users it seems to be important that a new update has been released. A new Android OS update for the series S22 has been released in April 2022 and updated security measurements and brought new features.

For Apple iPhone 13 it has been talked a lot about green. The generation 13 has been the first Flagship model to be produced in this colour, therefore it makes sense that people discuss about it.

Sentiment Analysis

Preprocessing Tweets

We need to preprocess data this time additionally with the following steps:

  • Emojis were replaced by the word form, e.g. Smiling emoji to smiling

  • Emoji Identifier were replaced by the word form, e.g. :-) to smiling

stopwords_regex <- paste(stopwords('en'), collapse = '\\b|\\b')
stopwords_regex <- paste0('\\b', stopwords_regex, '\\b')

Samsung_df <- samsung_df$text %>%
  str_to_lower() %>% #all text to lower case
  replace_contraction() %>% #replaces contractions to longer form
  replace_internet_slang() %>% #replaces common internet slang
  replace_hash(replacement = "") %>% #removes hashtags
  replace_word_elongation() %>% #removes word elongation, e.g. "heeeeey" to "hey"
  replace_emoji() %>% #replaces emojis with the word form 
  replace_emoji_identifier() %>% #replaces emoji identifiers to word form 
  replace_non_ascii() %>% #replaces common non-ASCII characters. 
  str_squish() %>% #reduces repeated whitespace inside a string
  str_trim() %>% #removes whitespace from start and end of string
  {gsub("(RT|via)((?:\\b\\W*@\\w+)+)","",.)} %>% #remove RT (retweets)
  {gsub("http[^[:blank:]]+","",.)} %>% #remove links that start with http
  {gsub("@\\u+","",.)} %>% #remove names 
  {gsub('@\\w+', '', .)} %>% # remove at people
  {gsub("[[:punct:]]"," ",.)} %>%#remove punctuation
  {gsub("[^[:alnum:]]"," ",.)}%>%#remove punctuation
  {gsub("pro"," ",.)}%>%#removes the word "pro" because its a different context herein
  stringr::str_replace_all(stopwords_regex, '') %>% #remove stop words
  unique()#remove duplicates

tail(Samsung_df)
[1] "samsung galaxy s22 s22 plus s22 ultra overheating issue  find  fix overheating issues     "             
[2] "     samsung s22 giveaway bro frowning face"                                                            
[3] "greetings   samsung galaxy s22 ultra "                                                                  
[4] "  want samsung s22 ultra"                                                                               
[5] " must  12 things   new samsung galaxy s22  s22  "                                                       
[6] "oneplus pad  amp  10  launch  honor magic x14  amp  x15  samsung s22 ultra  1tb  digital payments fire "
Apple_df <- apple_df$text %>%
  str_to_lower() %>% #all text to lower case
  replace_contraction() %>% #replaces contractions to longer form
  replace_internet_slang() %>% #replaces common internet slang
  replace_hash(replacement = "") %>% #removes hashtags
  replace_word_elongation() %>% #removes word elongation, e.g. "heeeeey" to "hey"
  replace_emoji() %>% #replaces emojis with the word form 
  replace_emoji_identifier() %>% #replaces emoji identifiers to word form 
  replace_non_ascii() %>% #replaces common non-ASCII characters. 
  str_squish() %>% #reduces repeated whitespace inside a string
  str_trim() %>% #removes whitespace from start and end of string
  {gsub("(RT|via)((?:\\b\\W*@\\w+)+)","",.)} %>% #remove RT (retweets)
  {gsub("http[^[:blank:]]+","",.)} %>% #remove links that start with http
  {gsub("@\\u+","",.)} %>% #remove names 
  {gsub('@\\w+', '', .)} %>% # remove at people
  {gsub("[[:punct:]]"," ",.)} %>%#remove punctuation
  {gsub("[^[:alnum:]]"," ",.)}%>%#remove punctuation
  {gsub("pro"," ",.)}%>%#removes the word "pro" because its a different context herein
  stringr::str_replace_all(stopwords_regex, '') %>% #remove stop words
  unique() #remove duplicates
  
  
tail(Apple_df)
[1] "hi friends  confetti ball full coverage soft tpu case  iphone 13 smiling cat face  heart eyes smiling cat face  heart eyes many colors hibiscus cherry blossom blossom   0 8 thumbs  thumbs  thumbs  wha    "
[2] "first world dilemma      get   wait        8    fritz   m  looking    "                                                                                                                                      
[3] "  1  issues downloading  new     "                                                                                                                                                                           
[4] "cute geometry art label transparent korean phone case  iphone     "                                                                                                                                          
[5] "happy adventurer  jun087  galaxy s21   artscase     "                                                                                                                                                        
[6] "  lock apps  iphone   passcode using shortcuts  hindi      "                                                                                                                                                 

Sentiments in Tweets

The sentiment analysis

On the first look, sentiments are similar for both smartphone models and are commented on with highly positive sentiments. This means that on both models, users are generally speaking positively about their smartphone.

Samsung S22 has more trust and anticipation while iPhone 13 brings more joy to its users but also more sadness, surprise, fear and disgust.

###### Sentimentr score #######
sentimentr_apple <- sentiment_by(Apple_df, by=NULL)
# You can see the sentiment per tweet ID:
ggplot(data=sentimentr_apple,aes(x=element_id,y=ave_sentiment, color=ave_sentiment))+
  geom_line()

# You can see the summary of minimum, IQR, median and mean for all variables. For us, word_count and ave_sentiment are mostly interesting:
summary(sentimentr_apple)
   element_id     word_count            sd       ave_sentiment    
 Min.   :   1   Min.   :  0.000   Min.   : NA    Min.   :-1.6310  
 1st Qu.:1829   1st Qu.:  6.000   1st Qu.: NA    1st Qu.: 0.0000  
 Median :3658   Median :  9.000   Median : NA    Median : 0.0625  
 Mean   :3658   Mean   :  9.507   Mean   :NaN    Mean   : 0.1205  
 3rd Qu.:5486   3rd Qu.: 12.000   3rd Qu.: NA    3rd Qu.: 0.2846  
 Max.   :7314   Max.   :135.000   Max.   : NA    Max.   : 1.7532  
                                  NA's   :7314                    
# You can see the variance and standard deviation for the Sentiment Score & Word Count:
data.frame(" "= c("Average", "Variance", "Standard Deviation"),
"Sentiment Score" = c(round(mean(sentimentr_apple$ave_sentiment),2), round(var(sentimentr_apple$ave_sentiment),2),
round(sd(sentimentr_apple$ave_sentiment),2)), 
"Word Count"=c(round(mean(sentimentr_apple$word_count),2), round(var(sentimentr_apple$word_count),2),
round(sd(sentimentr_apple$word_count),2)))
##### Sentimentr score ######
sentimentr_samsung <- sentiment_by(Samsung_df, by=NULL)
# You can see the sentiment per tweet ID:
ggplot(data=sentimentr_samsung,aes(x=element_id,y=ave_sentiment, color=ave_sentiment))+
  geom_line()


# You can see the summary of minimum, IQR, median and mean for all variables. For us, word_count and ave_sentiment are mostly interesting:
summary(sentimentr_samsung)
   element_id     word_count          sd       ave_sentiment     
 Min.   :   1   Min.   : 0.00   Min.   : NA    Min.   :-1.10940  
 1st Qu.: 766   1st Qu.: 8.00   1st Qu.: NA    1st Qu.: 0.00000  
 Median :1531   Median :10.00   Median : NA    Median : 0.07071  
 Mean   :1531   Mean   :10.32   Mean   :NaN    Mean   : 0.11989  
 3rd Qu.:2296   3rd Qu.:13.00   3rd Qu.: NA    3rd Qu.: 0.26726  
 Max.   :3061   Max.   :34.00   Max.   : NA    Max.   : 1.59250  
                                NA's   :3061                     
# You can see the variance and standard deviation for the Sentiment Score & Word Count:
data.frame(" "= c("Average", "Variance", "Standard Deviation"),
"Sentiment Score" = c(round(mean(sentimentr_samsung$ave_sentiment),2), round(var(sentimentr_samsung$ave_sentiment),2),
round(sd(sentimentr_samsung$ave_sentiment),2)), 
"Word Count"=c(round(mean(sentimentr_samsung$word_count),2), round(var(sentimentr_samsung$word_count),2),
round(sd(sentimentr_samsung$word_count),2)))

Samsung S22 tweets were on average 10.4 words long while Apple iPhone 13 tweets had 9.9 words. The tweet with the maximum number of words was about iPhone 13 with 135 identified words. Samsung S22 with 34 words maximum words is quite shorter.

The sentimentr package in R estimates the sentiment polarity by sentence. The average sentiment for iPhone 13 was higher distributed with a range from -1.6 to +1.9 with its average at 0.26 while Samsung had a sentiment polarity from -1.1 to +1.6 with its average at 0.15. The higher variance within the data is identical to our findings from the plot “Relative Sentiment Score based on Tweets about Apple and Samsung” earlier. We can see from this that iPhone 13 users are in general more emotional - in a negative and positive direction - than Samsung S22 users. We assume that people are emotionally more dependent on their iPhone 13 than Samsung S22.

To see the sentiments per tweet, generate this HTML files:

Sentiment Terms

Now we want to extract the sentiment terms for both phones. What is liked by the users? What is not?

Samsung S22

Selecting by weightage

Scandal is related to the GOS app that slowed Samsung phones down on purpose to save battery life without notifying the user about it.

Apple iPhone 13

Selecting by weightage

Word Correlation

Samsung S22

Warning: `distinct_()` was deprecated in dplyr 0.7.0.
Please use `distinct()` instead.
See vignette('programming') for more help
This warning is displayed once every 8 hours.
Call `lifecycle::last_warnings()` to see where this warning was generated.

Apple iPhone 13

Warning: ggrepel: 3 unlabeled data points (too many overlaps). Consider increasing max.overlaps

Clustering

tdm_s <- corpus<- Corpus(VectorSource(word_s)) 
tdm_s <- TermDocumentMatrix(tdm_s)
tdm_s2 <- removeSparseTerms(tdm_s, sparse = 0.95)
ms2 <- as.matrix(tdm_s2)
# cluster terms
distMatrix_s <- dist(scale(ms2))
fit_s <- hclust(distMatrix_s, method = "ward.D")
plot(fit_s)
rect.hclust(fit_s, k = 6,border = "red") # cut tree into 6 clusters

tdm_a <- corpus<- Corpus(VectorSource(word_a)) 
tdm_a <- TermDocumentMatrix(tdm_a)
tdm_a2 <- removeSparseTerms(tdm_a, sparse = 0.95)
ma2 <- as.matrix(tdm_a2)
# cluster terms
distMatrix_a <- dist(scale(ma2))
fit_a <- hclust(distMatrix_a, method = "ward.D")
plot(fit_a)
rect.hclust(fit_a, k = 6,border = "red") # cut tree into 6 clusters

LDA Topic Modelling

Samsung S22

$CTM
      Topic 1  Topic 2   Topic 3   Topic 4 Topic 5  
 [1,] "phone"  "camera"  "new"     "phone" "phone"  
 [2,] "get"    "phone"   "camera"  "case"  "seri"   
 [3,] "seri"   "use"     "just"    "seri"  "new"    
 [4,] "new"    "new"     "seri"    "new"   "case"   
 [5,] "now"    "get"     "phone"   "updat" "camera" 
 [6,] "featur" "case"    "best"    "can"   "plus"   
 [7,] "will"   "note"    "plus"    "plus"  "updat"  
 [8,] "offer"  "featur"  "android" "cover" "android"
 [9,] "sale"   "android" "use"     "get"   "now"    
[10,] "got"    "now"     "one"     "buy"   "buy"    

$VEM
      Topic 1 Topic 2     Topic 3  Topic 4  Topic 5 
 [1,] "phone" "new"       "phone"  "seri"   "phone" 
 [2,] "case"  "camera"    "camera" "new"    "seri"  
 [3,] "new"   "seri"      "new"    "phone"  "case"  
 [4,] "can"   "can"       "plus"   "got"    "get"   
 [5,] "use"   "smartphon" "featur" "now"    "use"   
 [6,] "now"   "just"      "upgrad" "see"    "featur"
 [7,] "get"   "best"      "one"    "upgrad" "updat" 
 [8,] "seri"  "screen"    "buy"    "will"   "one"   
 [9,] "buy"   "one"       "deal"   "note"   "camera"
[10,] "just"  "pen"       "just"   "cover"  "plus"  

$VEM_Fixed
      Topic 1 Topic 2     Topic 3  Topic 4  Topic 5 
 [1,] "phone" "new"       "phone"  "seri"   "phone" 
 [2,] "case"  "camera"    "camera" "new"    "seri"  
 [3,] "new"   "seri"      "new"    "phone"  "case"  
 [4,] "can"   "can"       "plus"   "got"    "get"   
 [5,] "use"   "smartphon" "featur" "now"    "use"   
 [6,] "now"   "just"      "upgrad" "see"    "featur"
 [7,] "get"   "screen"    "one"    "upgrad" "updat" 
 [8,] "seri"  "best"      "buy"    "will"   "one"   
 [9,] "buy"   "one"       "deal"   "note"   "camera"
[10,] "just"  "pen"       "just"   "cover"  "plus"  

$Gibbs
      Topic 1   Topic 2   Topic 3  Topic 4     Topic 5  
 [1,] "game"    "month"   "phone"  "\"best"    "avail"  
 [2,] "chang"   "xiaomi"  "seri"   "green"     "perform"
 [3,] "arriv"   "product" "new"    "model"     "last"   
 [4,] "think"   "premium" "case"   "let"       "tri"    
 [5,] "variant" "back"    "camera" "spec"      "charger"
 [6,] "attract" "home"    "get"    "deliv"     "feel"   
 [7,] "claim"   "may"     "use"    "cell"      "due"    
 [8,] "clear"   "live"    "best"   "laugh"     "taken"  
 [9,] "epic"    "connect" "updat"  "sboxmavcj" "keep"   
[10,] "money"   "expect"  "plus"   "trick"     "bad"    

      CTM.1       VEM.1 VEM_Fixed.1     Gibbs.1 
          5           1           1           3 

The topics about “seri”, “now”, “camera”, “update” relates to the S22 Ultra’s April patch that introduced many camera-related features.

Apple iPhone 13

$CTM
      Topic 1 Topic 2   Topic 3 Topic 4 Topic 5   Topic 6 Topic 7   Topic 8 Topic 9  Topic 10
 [1,] "mini"  "case"    "use"   "just"  "new"     "phone" "phone"   "get"   "phone"  "phone" 
 [2,] "phone" "new"     "get"   "green" "phone"   "new"   "just"    "case"  "new"    "case"  
 [3,] "just"  "get"     "green" "get"   "case"    "get"   "like"    "can"   "just"   "camera"
 [4,] "case"  "mini"    "case"  "use"   "use"     "buy"   "case"    "got"   "case"   "like"  
 [5,] "use"   "green"   "buy"   "buy"   "get"     "now"   "camera"  "want"  "get"    "will"  
 [6,] "get"   "one"     "want"  "will"  "buy"     "want"  "buy"     "will"  "use"    "want"  
 [7,] "one"   "now"     "phone" "now"   "batteri" "use"   "get"     "win"   "green"  "mini"  
 [8,] "can"   "batteri" "got"   "case"  "can"     "like"  "got"     "need"  "camera" "amp"   
 [9,] "like"  "like"    "amp"   "can"   "want"    "one"   "batteri" "give"  "can"    "win"   
[10,] "new"   "want"    "will"  "like"  "now"     "got"   "amp"     "day"   "will"   "can"   

$VEM
      Topic 1 Topic 2 Topic 3 Topic 4  Topic 5 Topic 6  Topic 7  Topic 8 Topic 9 Topic 10
 [1,] "get"   "green" "green" "new"    "phone" "phone"  "phone"  "like"  "new"   "new"   
 [2,] "phone" "case"  "case"  "use"    "get"   "get"    "new"    "case"  "green" "use"   
 [3,] "case"  "want"  "new"   "camera" "want"  "case"   "want"   "phone" "mini"  "phone" 
 [4,] "just"  "got"   "use"   "buy"    "can"   "buy"    "just"   "want"  "like"  "mini"  
 [5,] "like"  "just"  "can"   "want"   "buy"   "can"    "camera" "one"   "amp"   "camera"
 [6,] "one"   "watch" "just"  "case"   "mini"  "mini"   "case"   "just"  "now"   "like"  
 [7,] "price" "good"  "got"   "can"    "new"   "camera" "amp"    "give"  "give"  "just"  
 [8,] "can"   "best"  "now"   "will"   "will"  "got"    "will"   "mini"  "plus"  "case"  
 [9,] "now"   "can"   "plus"  "one"    "got"   "one"    "use"    "new"   "know"  "price" 
[10,] "got"   "use"   "need"  "win"    "one"   "new"    "now"    "look"  "win"   "can"   

$VEM_Fixed
      Topic 1 Topic 2 Topic 3 Topic 4  Topic 5 Topic 6  Topic 7  Topic 8 Topic 9 Topic 10
 [1,] "get"   "green" "green" "new"    "phone" "phone"  "phone"  "like"  "new"   "new"   
 [2,] "phone" "case"  "case"  "use"    "get"   "get"    "new"    "case"  "green" "use"   
 [3,] "case"  "want"  "new"   "camera" "want"  "case"   "want"   "phone" "mini"  "phone" 
 [4,] "just"  "got"   "use"   "buy"    "can"   "buy"    "just"   "want"  "like"  "camera"
 [5,] "like"  "just"  "can"   "want"   "buy"   "can"    "camera" "one"   "amp"   "mini"  
 [6,] "one"   "watch" "just"  "case"   "mini"  "mini"   "case"   "just"  "now"   "like"  
 [7,] "price" "good"  "got"   "can"    "new"   "camera" "amp"    "give"  "give"  "just"  
 [8,] "can"   "best"  "now"   "will"   "will"  "got"    "will"   "mini"  "know"  "case"  
 [9,] "now"   "can"   "plus"  "one"    "got"   "one"    "use"    "new"   "plus"  "price" 
[10,] "got"   "use"   "need"  "win"    "one"   "new"    "now"    "avail" "win"   "can"   

$Gibbs
      Topic 1   Topic 2    Topic 3      Topic 4   Topic 5   Topic 6 Topic 7   Topic 8   Topic 9    Topic 10 
 [1,] "septemb" "mode"     "prank"      "cat"     "wall"    "phone" "expect"  "regist"  "plug"     "die"    
 [2,] "lock"    "care"     "jailbreak"  "rate"    "special" "case"  "auto"    "\"cute"  "headphon" "matter" 
 [3,] "annoy"   "\"got"    "deliv"      "bot"     "opinion" "get"   "pixel"   "eidi"    "notif"    "includ" 
 [4,] "seat"    "circl"    "imag"       "channel" "foldabl" "new"   "compani" "prize"   "question" "delet"  
 [5,] "success" "min"      "resist"     "cuti"    "side"    "just"  "comput"  "\"buy"   "wit"      "email"  
 [6,] "\"peopl" "total"    "carri"      "friday"  "cost"    "use"   "freez"   "current" "anim"     "kinda"  
 [7,] "plate"   "bar"      "content"    "sinc"    "free"    "can"   "magnet"  "factori" "concert"  "outsid" 
 [8,] "portabl" "friend"   "fraud"      "address" "open"    "buy"   "regular" "fund"    "care"     "token"  
 [9,] "proof"   "internet" "girlfriend" "compact" "rang"    "want"  "remind"  "icon"    "despit"   "fav"    
[10,] "school"  "kept"     "may"        "advanc"  "trash"   "green" "past"    "overh"   "exact"    "mini\","

      CTM.1       VEM.1 VEM_Fixed.1     Gibbs.1 
         10           1           1           6 

Amazon Review Analysis

Data Input

[1] 110   5
 review_title       review_text        review_star        review_date             page       
 Length:110         Length:110         Length:110         Length:110         Min.   : 1.000  
 Class :character   Class :character   Class :character   Class :character   1st Qu.: 2.000  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character   Median : 5.000  
                                                                             Mean   : 5.091  
                                                                             3rd Qu.: 8.000  
                                                                             Max.   :10.000  
[1] 507   5
 review_title       review_text        review_star        review_date             page      
 Length:507         Length:507         Length:507         Length:507         Min.   : 1.00  
 Class :character   Class :character   Class :character   Class :character   1st Qu.: 6.00  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character   Median :15.00  
                                                                             Mean   :17.09  
                                                                             3rd Qu.:28.00  
                                                                             Max.   :40.00  

Data Preprocessing

shifted.words <- iphone.reviews.text %>%
  unnest_tokens(bigram, review_text, token = "ngrams", n = 2)%>%
  dplyr::count(bigram, sort = TRUE) %>%
  separate(bigram, c("word1", "word2"), sep = " ")%>%
  filter(word1 %in% negation.words & !word2 %in% stop_words$word)%>%
  inner_join(get_sentiments("bing"), by = c(word2 = "word"))%>%
  mutate(sentiment = ifelse(sentiment == "positive", 1, -1)) %>%
  mutate(score = sentiment * n) %>%
  mutate(word2 = reorder(word2, score))

shifted.words

iphone.reviews.text <- mgsub(iphone.reviews.text$review_text, negated.phrases, synonyms) %>%
  dplyr::as_data_frame() %>%
  rename(review_text = value)

iphone.reviews.text

Wordcloud

Joining, by = "word"
Joining, by = "word"

Joining, by = "word"
Joining, by = "word"

Sentiment Analysis

Joining, by = "word"
Joining, by = "word"
Joining, by = "word"

Joining, by = "word"
Joining, by = "word"
Joining, by = "word"

# Bing Samsung
bing.mean.score_s <- word.freq.table_s %>% 
  inner_join(get_sentiments("bing")) %>%
  mutate(sentiment = ifelse(sentiment == "positive", 1, -1)) %>%
  summarise(Samsung_mean = mean(sentiment))
Joining, by = "word"
bing.mean.score_a <- word.freq.table_a %>% 
  inner_join(get_sentiments("bing")) %>%
  mutate(sentiment = ifelse(sentiment == "positive", 1, -1)) %>%
  summarise(Apple_mean = mean(sentiment))
Joining, by = "word"
data.frame(bing.mean.score_s, bing.mean.score_a)
NA
#Samsung
# rescale the range to 5 star range.
bing.mean.score_s<-rescale(bing.mean.score_s$mean, to = c(1,5), from = c(-1,1))
Warning: Unknown or uninitialised column: `mean`.
# Afinn scores are from -5 to 5.
afinn.mean.score_s <- word.freq.table_s %>% 
  inner_join(get_sentiments("afinn"))%>%
  summarise(Samsung_mean = mean(value))
Joining, by = "word"
# rescale the range to 5 star range.
afinn.mean.score_s<-rescale(afinn.mean.score_s$Samsung_mean, to = c(1,5), from = c(-5,5))

#Apple
# rescale the range to 5 star range.
bing.mean.score_a<-rescale(bing.mean.score_a$mean, to = c(1,5), from = c(-1,1))
Warning: Unknown or uninitialised column: `mean`.
# Afinn scores are from -5 to 5.
afinn.mean.score_a <- word.freq.table_a %>% 
  inner_join(get_sentiments("afinn"))%>%
  summarise(Apple_mean = mean(value))
Joining, by = "word"
# rescale the range to 5 star range.
afinn.mean.score_a<-rescale(afinn.mean.score_a$Apple_mean, to = c(1,5), from = c(-5,5))
afinn.mean.score_a
[1] 3.117557
data.table(afinn.mean.score_s, afinn.mean.score_a)

Word Correlation

# Correlation Terms
# The correlation of appearing together in a review
samsung.correlation.terms <- samsung.reviews.text %>%
  mutate(review = row_number()) %>%
  unnest_tokens(word, review_text) %>%
  filter(!word %in% stop_words$word) %>%
  group_by(word) %>%
  filter(n() >=7)%>%
  pairwise_cor(word, review, sort = TRUE)
samsung.correlation.terms

library(ggraph)
library(igraph)
samsung.correlation.terms %>%
  filter(correlation >= 0.50) %>%
  graph_from_data_frame() %>%
  ggraph(layout = "igraph", algorithm = "kk") +
  geom_edge_link(aes(alpha = correlation), 
                 show.legend = FALSE)+
  geom_node_point(color = "lightblue", size = 2) +
  geom_node_text(aes(label = name), repel = TRUE) +
  theme_void()+
  ggtitle("Correlation of terms in Samsung S22 Reviews")

# Correlation Terms
# The correlation of appearing together in a review
apple.correlation.terms <- iphone.reviews.text %>%
  mutate(review = row_number()) %>%
  unnest_tokens(word, review_text) %>%
  filter(!word %in% stop_words$word) %>%
  group_by(word) %>%
  filter(n() >= 5)%>%
  pairwise_cor(word, review, sort = TRUE)
apple.correlation.terms

library(ggraph)
library(igraph)
apple.correlation.terms %>%
  filter(correlation >= 0.50) %>%
  graph_from_data_frame() %>%
  ggraph(layout = "igraph", algorithm = "kk") +
  geom_edge_link(aes(alpha = correlation), 
                 show.legend = FALSE)+
  geom_node_point(color = "lightblue", size = 2) +
  geom_node_text(aes(label = name), repel = TRUE) +
  theme_void()+
  ggtitle("Correlation of terms in Apple iPhone 13 Reviews")

bigrams.network.df_s <- samsung.reviews.text %>%
  unnest_tokens(bigram, review_text, token = "ngrams", n = 2) %>%
  separate(bigram, c("word1", "word2"), sep = " ") %>%
  filter(!word1 %in% stop_words$word & !word2 %in% stop_words$word) %>%
  dplyr::count(word1, word2, sort = TRUE) %>%
  filter(n > 5)

bigrams.network_s <- graph_from_data_frame(bigrams.network.df_s)
bigrams.network_s
IGRAPH 6694d76 DN-- 12 8 -- 
+ attr: name (v/c), n (e/n)
+ edges from 6694d76 (vertex names):
[1] battery->life      s22    ->ultra     13     ->pro       iphone ->13        pro    ->max       screen ->protector galaxy ->s22      
[8] samsung->galaxy   
bigrams.network.df_a <-iphone.reviews.text %>%
  unnest_tokens(bigram, review_text, token = "ngrams", n = 2) %>%
  separate(bigram, c("word1", "word2"), sep = " ") %>%
  filter(!word1 %in% stop_words$word & !word2 %in% stop_words$word) %>%
  dplyr::count(word1, word2, sort = TRUE) %>%
  filter(n > 2)

bigrams.network_a <- graph_from_data_frame(bigrams.network.df_a)
Warning in graph_from_data_frame(bigrams.network.df_a) :
  In `d' `NA' elements were replaced with string "NA"
bigrams.network_a
IGRAPH 44cf8f6 DN-- 92 75 -- 
+ attr: name (v/c), n (e/n)
+ edges from 44cf8f6 (vertex names):
 [1] iphone    ->13          battery   ->life        NA        ->NA          iphone    ->12          camera    ->quality    
 [6] battery   ->backup      iphone    ->11          android   ->user        pro       ->max         13        ->pro        
[11] amazing   ->phone       picture   ->quality     apple     ->products    cinematic ->mode        iphone    ->user       
[16] nice      ->product     phone     ->12          service   ->centre      time      ->iphone      amazing   ->battery    
[21] android   ->phone       buy       ->iphone      iphone    ->7           original  ->product     phone     ->13         
[26] refresh   ->rate        sound     ->quality     amazing   ->camera      battery   ->performance buy       ->samsung    
[31] camera    ->battery     camera    ->lens        heating   ->issues      iphone    ->6s          iphone    ->8          
[36] mind      ->blowing     nice      ->phone       night     ->mode        oneplus   ->5t          user      ->experience 
+ ... omitted several edges
# now we find the centrality measures of the network
# degree:the number of its adjacent edges (measure of direct influence)
deg_s <- degree(bigrams.network_s, mode = "all")

#K-core decomposition allows us to identify the core and the periphery of the network. A k-core is a maximal subnet of a network such that all nodes have at least degree K.
core_s <- coreness(bigrams.network_s, mode = "all")

# betweenness measures brokerage or gatekeeping potential. It is (approximately) the number of shortest paths between nodes that pass through a particular node.
betw_s <- betweenness(bigrams.network_s)

#Eigenvector centrality is a measure of being well-connected connected to the well-connected. First eigenvector of the graph adjacency matrix. Only works with undirected networks.
eigen_s <- eigen_centrality(bigrams.network_s, directed = TRUE)
Warning in eigen_centrality(bigrams.network_s, directed = TRUE) :
  At centrality.c:333 :graph is directed and acyclic; eigenvector centralities will be zeros
members_s <- cluster_walktrap(bigrams.network_s)

library(igraph)
bigrams.network_s <- simplify(bigrams.network_s
                            #remove.multiple = FALSE, #error occured ?
                            #remove.loops = TRUE)
)
V(bigrams.network_s)$color <- members$membership+1
Error: object 'members' not found
# now we find the centrality measures of the network
# degree:the number of its adjacent edges (measure of direct influence)
deg_s <- degree(bigrams.network_s, mode = "all")

#K-core decomposition allows us to identify the core and the periphery of the network. A k-core is a maximal subnet of a network such that all nodes have at least degree K.
core_s <- coreness(bigrams.network_s, mode = "all")

# betweenness measures brokerage or gatekeeping potential. It is (approximately) the number of shortest paths between nodes that pass through a particular node.
betw_s <- betweenness(bigrams.network_s)

#Eigenvector centrality is a measure of being well-connected connected to the well-connected. First eigenvector of the graph adjacency matrix. Only works with undirected networks.
eigen_s <- eigen_centrality(bigrams.network_s, directed = TRUE)
Warning in eigen_centrality(bigrams.network_s, directed = TRUE) :
  At centrality.c:333 :graph is directed and acyclic; eigenvector centralities will be zeros
members_s <- cluster_walktrap(bigrams.network_s)

library(igraph)
bigrams.network_s <- simplify(bigrams.network_s
                            #remove.multiple = FALSE, #error occured ?
                            #remove.loops = TRUE)
)
V(bigrams.network_s)$color <- members_s$membership+1

# Using "Coreness" as size
# Coreness -> mean (average distance to all the other nodes, diffusion of information)
plot(bigrams.network_s,
     layout = layout_with_fr,
     vertex.label.color = "black",
     vertex.label.cex = 0.9,
     vertex.label.dist = 0,
     vertex.frame.color = 0,
     vertex.size = core_s*10, 
     edge.arrow.size = 0.01,
     edge.curved = 0.7,
     edge.color = "gray",
     main = "Bigram Communities (Samsung)"
)
mtext("Coreness")


# Using "Degree" as size
# degree=mode (number of edges of the node, in-degree:prestige

plot(bigrams.network_s,
     layout = layout_with_fr,
     vertex.label.color = "black",
     vertex.label.cex = 0.9,
     vertex.label.dist = 0,
     vertex.frame.color = 0,
     vertex.size = deg_s, 
     edge.arrow.size = 0.01,
     edge.curved = 0.7,
     edge.color = "gray",
     main = "Bigram Communities (Samsung)"
)
mtext("Degree")


# Using "Eigenvector Centrality" as size
# centrality (the most connected words)
plot(bigrams.network_s,
     layout = layout_with_fr,
     vertex.label.color = "black",
     vertex.label.cex = 0.8,
     vertex.label.dist = 0,
     vertex.size = eigen_s$vector*20, 
     edge.arrow.size = 0.01,
     edge.curved = 0.7,
     edge.color = "black",
     main = "Bigram Communities (Samsung)"
)
mtext("Eigenvector Centrality")


# Using "Betweenness" as size
#Betweenness -> median (weighted # of paths going through the node)
plot(bigrams.network_s,
     layout = layout_with_fr,
     vertex.label.color = "black",
     vertex.label.cex = 0.8,
     vertex.label.dist = 0,
     vertex.size = betw_s, 
     edge.arrow.size = 0.01,
     edge.curved = 0.7,
     edge.color = "lightgrey",
     main = "Bigram Communities (Samsung)"
)
mtext("Betweenness")

# now we find the centrality measures of the network
# degree:the number of its adjacent edges (measure of direct influence)
deg_a <- degree(bigrams.network_a, mode = "all")

#K-core decomposition allows us to identify the core and the periphery of the network. A k-core is a maximal subnet of a network such that all nodes have at least degree K.
core_a <- coreness(bigrams.network_a, mode = "all")

# betweenness measures brokerage or gatekeeping potential. It is (approximately) the number of shortest paths between nodes that pass through a particular node.
betw_a <- betweenness(bigrams.network_a)

#Eigenvector centrality is a measure of being well-connected connected to the well-connected. First eigenvector of the graph adjacency matrix. Only works with undirected networks.
eigen_a <- eigen_centrality(bigrams.network_a, directed = TRUE)
members_a <- cluster_walktrap(bigrams.network_a)

library(igraph)
bigrams.network_a <- simplify(bigrams.network_a
                            #remove.multiple = FALSE, #error occured ?
                            #remove.loops = TRUE)
)
V(bigrams.network_a)$color <- members_a$membership+1

# Using "Coreness" as size
# Coreness -> mean (average distance to all the other nodes, diffusion of information)
plot(bigrams.network_a,
     layout = layout_with_fr,
     vertex.label.color = "black",
     vertex.label.cex = 0.9,
     vertex.label.dist = 0,
     vertex.frame.color = 0,
     vertex.size = core_a*10, 
     edge.arrow.size = 0.01,
     edge.curved = 0.7,
     edge.color = "gray",
     main = "Bigram Communities (iPhone 13)"
)
mtext("Coreness")


# Using "Degree" as size
# degree=mode (number of edges of the node, in-degree:prestige

plot(bigrams.network_a,
     layout = layout_with_fr,
     vertex.label.color = "black",
     vertex.label.cex = 0.9,
     vertex.label.dist = 0,
     vertex.frame.color = 0,
     vertex.size = deg_a, 
     edge.arrow.size = 0.01,
     edge.curved = 0.7,
     edge.color = "gray",
     main = "Bigram Communities (iPhone 13)"
)
mtext("Degree")


# Using "Eigenvector Centrality" as size
# centrality (the most connected words)
plot(bigrams.network_a,
     layout = layout_with_fr,
     vertex.label.color = "black",
     vertex.label.cex = 0.8,
     vertex.label.dist = 0,
     vertex.size = eigen_a$vector*20, 
     edge.arrow.size = 0.01,
     edge.curved = 0.7,
     edge.color = "black",
     main = "Bigram Communities (iPhone 13)"
)
mtext("Eigenvector Centrality")


# Using "Betweenness" as size
#Betweenness -> median (weighted # of paths going through the node)
plot(bigrams.network_a,
     layout = layout_with_fr,
     vertex.label.color = "black",
     vertex.label.cex = 0.8,
     vertex.label.dist = 0,
     vertex.size = betw_a, 
     edge.arrow.size = 0.01,
     edge.curved = 0.7,
     edge.color = "lightgrey",
     main = "Bigram Communities (iPhone 13)"
)
mtext("Betweenness")

LS0tCnRpdGxlOiAiQnJhbmQgQW5hbHlzaXMgb2YgU2Ftc3VuZyBTMjIgYW5kIEFwcGxlIGlQaG9uZSAxMyBDb21wYXJpc29uIgphdXRob3JzOiBNb2hpdCBSYXRob2QsIFNocnV0aGkgWWFtYWphbGEsIFpoaXl1IFd1LCBNYXJpZSBMaXNhbm5lIFNjaMO8cm1hbm4Kb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKLS0tCgojIEFuYWx5c2lzIG9mIFNhbXN1bmcgUzIyIGFuZCBBcHBsZSBpUGhvbmUgMTMKCiMjIFRoZSBTbWFydHBob25lIE1hcmtldAoKVGhlIGdsb2JhbCBzbWFydHBob25lIG1hcmtldCBoYXMgZXhwZXJpZW5jZWQgbXVsdGlwbGUgbWFya2V0IGxlYWRlcnMgb3ZlciB0aGUgcGFzdCBmZXcgeWVhcnMuIFRoZSBvbmx5IHR3byBtYWpvciBicmFuZHMgdGhhdCByZW1haW5lZCBvdmVyIHRoZSB5ZWFycyB3ZXJlIEFwcGxlIGFuZCBTYW1zdW5nLiBUaG9zZSB0d28gYnJhbmRzIGFyZSBjb21wYXJlZCByZWd1bGFybHkgYW5kIGFyZSBjb21wZXRpbmcgb3ZlciB0aGUgbWFya2V0IHNoYXJlLiBXaGlsZSBTYW1zdW5nIHdhcyB0aGUgbWFya2V0IGxlYWRlciBpbiB0aGUgZmlyc3QgdGhyZWUgcXVhcnRlcnMgaW4gMjAyMS4gSW4gU2VwdGVtYmVyIDIwMjEsIEFwcGxlIHJlbGVhc2VkIGl0cyBuZXcgaVBob25lIG1vZGVsIHdpdGggdGhlIGdlbmVyYXRpb24gMTMgYW5kIGdhaW5lZCBtYXJrZXQgc2hhcmUsIHRha2luZyBvdmVyIHRoZSBtYXJrZXQgbGVhZGVyIHBvc2l0aW9uLiBJbiBGZWJydWFyeSAyMDIyLCBTYW1zdW5nIGFsc28gcmVsZWFzZWQgdGhlIG5ldyBtb2RlbCBpbiBpdHMgR2FsYXh5IHNlcmllcy4gVGhvc2UgdHdvIHBob25lcyBhcmUgdGhlIGZsYWdzaGlwcyBpbiB0aGUgY3VycmVudCBzbWFydHBob25lIG1hcmtldC4KCiFbXShpbWFnZXMvcGFzdGUtM0M2NThEMDYucG5nKQoKU291cmNlOiBbSURDLiAoMjAyMikuwqBHbG9iYWwgc21hcnRwaG9uZSBtYXJrZXQgc2hhcmUgZnJvbSA0dGggcXVhcnRlciAyMDA5IHRvIDR0aCBxdWFydGVyIDIwMjEgKGJ5IHZlbmRvcikuwqBTdGF0aXN0YS4gU3RhdGlzdGEgSW5jLi5dKGh0dHBzOi8vd3d3LnN0YXRpc3RhLmNvbS9zdGF0aXN0aWNzLzI3MTQ5Ni9nbG9iYWwtbWFya2V0LXNoYXJlLWhlbGQtYnktc21hcnRwaG9uZS12ZW5kb3JzLXNpbmNlLTR0aC1xdWFydGVyLTIwMDkvKSBBY2Nlc3NlZDogQXByaWwgMTQsIDIwMjIuCgojIyBTYW1zdW5nIEdhbGF4eSBTMjIKClRoZSBTYW1zdW5nIEdhbGF4eSBTIHNlcmllcyBpcyB0aGUgaGlnaC1lbmQgbW9kZWwgcHJvZHVjZWQgYW5kIHNvbGQgYnkgU2Ftc3VuZywgYSBTb3V0aCBLb3JlYW4gbXVsdGluYXRpb25hbCBlbGVjdHJvbmljcyBjb21wYW55LiBUaGUgUyBzZXJpZXMgaGFzIDEzIGdlbmVyYXRpb25zLiBUb2dldGhlciB3aXRoIHRoZSBHYWxheHkgWiBhbmQgR2FsYXh5IE5vdGUgKGRpc2NvbnRpbnVlZCkgc2VyaWVzLCB0aGUgUyBzZXJpZXMgc2VydmVzIGFzIGZsYWdzaGlwIG1vZGVscyAoW1dpa2lwZWRpYSwgbi5kLildKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1NhbXN1bmdfR2FsYXh5X1Nfc2VyaWVzICJXaWtpcGVkaWEgU2Ftc3VuZyBHYWxheHkgUyBzZXJpZXMiKS4gU2Ftc3VuZyBTIHNlcmllcyB1c2VzIHRoZSBvcGVuIHNvdXJjZSBvcGVyYXRpbmcgc3lzdGVtIEFuZHJvaWQgKFtTYW1zdW5nXShodHRwczovL3d3dy5zYW1zdW5nLmNvbS9pZS9zbWFydHBob25lcy9nYWxheHktczIyLXVsdHJhLykpLgoKSW4gRmVicnVhcnkgMjAyMiB0aGUgbW9kZWwgUzIyIHdhcyByZWxlYXNlZCBpbiB0aHJlZSB2YXJpYW50czogUzIyLCBTMjIgUGx1cyAoYWxzbzogUzIyKykgYW5kIFMyMiBVbHRyYSAoW1dpa2lwZWRpYSwgbi5kLildKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1NhbXN1bmdfR2FsYXh5X1Nfc2VyaWVzICJXaWtpcGVkaWEgU2Ftc3VuZyBHYWxheHkgUyBzZXJpZXMiKS4gSXQgY29tZXMgaW4gdGhlIGNvbG91cnMgdGhhdCBhcmUgc2hvd24gaW4gdGhlIHBpY3R1cmUgYmVsb3csIG5hbWVseTogcGhhbnRvbSB3aGl0ZSwgYnVyZ3VuZHksIHBoYW50b20gYmxhY2sgYW5kIGdyZWVuIChbU2Ftc3VuZ10oaHR0cHM6Ly93d3cuc2Ftc3VuZy5jb20vaWUvc21hcnRwaG9uZXMvZ2FsYXh5LXMyMi11bHRyYS8pKS4gQWxzbyB0aGUgUzIyIFVsdHJhIHZhcmlhbnQgY29tZXMgd2l0aCBhbiBzby1jYWxsZWQgIlMgUGVuIiB3aGljaCBsZXRzIHRoZSB1c2VyIHdyaXRlIG9uIHRoZWlyIHBob25lIGFuZCBjYW4gYmUgcmVjaGFyZ2VkIHdpdGhpbiB0aGUgcGhvbmUgKFtTYW1zdW5nXShodHRwczovL3d3dy5zYW1zdW5nLmNvbS9pZS9zbWFydHBob25lcy9nYWxheHktczIyLXVsdHJhLykpLgoKU2Ftc3VuZyBhZHZlcnRpc2VzIHRoZSBTMjIgc2VyaWVzIHdpdGggdGhlIGZvbGxvd2luZyBmZWF0dXJlczoKCi0gICAiVGhlIHBob25lIHRoYXQgbWFrZXMgZXZlcnlkYXkgZXBpYwoKLSAgIE5pZ2h0b2dyYXBoeSBjYW1lcmEKCi0gICBBIGJhdHRlcnkgdGhhdCBsYXN0cyB0aGUgZGF5IGFuZCBiZXlvbmQKCi0gICBPdXIgZmFzdGVzdCBjaGlwIGV2ZXIiCgooU291cmNlOiBbU2Ftc3VuZ10oaHR0cHM6Ly93d3cuc2Ftc3VuZy5jb20vaWUvc21hcnRwaG9uZXMvZ2FsYXh5LXMyMi8pKQoKWyFbXShodHRwczovL2ltZy5nbG9iYWwubmV3cy5zYW1zdW5nLmNvbS9nbG9iYWwvd3AtY29udGVudC91cGxvYWRzLzIwMjIvMDIvR2FsYXh5LVMyMi1TMjItcHJfbWFpbjEuanBnICJTYW1zdW5nIFMyMiIpe3dpZHRoPSI3MDcifV0oaHR0cHM6Ly9pbWcuZ2xvYmFsLm5ld3Muc2Ftc3VuZy5jb20vZ2xvYmFsL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDIyLzAyL0dhbGF4eS1TMjItUzIyLXByX21haW4xLmpwZykKCltQaWN0dXJlIFNvdXJjZV0oaHR0cHM6Ly9pbWcuZ2xvYmFsLm5ld3Muc2Ftc3VuZy5jb20vZ2xvYmFsL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDIyLzAyL0dhbGF4eS1TMjItUzIyLXByX21haW4xLmpwZykKCiMjIEFwcGxlIGlQaG9uZSAxMwoKVGhlIEFwcGxlIGlQaG9uZSBzZXJpZXMgaXMgdGhlIG9ubHkgc21hcnRwaG9uZSBzZXJpZXMgcHJvZHVjZWQgYW5kIHNvbGQgYnkgQXBwbGUgSW5jLCBhbiBVUy1BbWVyaWNhbiBtdWx0aW5hdGlvbmFsIHRlY2hub2xvZ3kgY29tcGFueSAoW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVBob25lKSkuCgpUaGUgZ2VuZXJhdGlvbiAxMyB3YXMgcmVsZWFzZWQgaW4gU2VwdGVtYmVyIDIwMjEgaW4gdGhyZWUgdmFyaWFudHM6IGlQaG9uZSAxMywgaVBob25lIDEzIG1pbmksIGlQaG9uZSAxMyBQcm8sIGlQaG9uZSAxMyBQcm8gTWF4IGFuZCBpUGhvbmUgU0UuIFRoZSByZWd1bGFyIHZhcmlhbnQgYW5kIG1pbmkgY2FuIGJlIGJvdWdodCBpbiB0aGUgY29sb3VyczogZ3JlZW4sIHBpbmssIGJsdWUsIG1pZG5pZ2h0LCBzdGFybGlnaHQsIHJlZC4gVGhlIHZhcmlhbnRzIFBybyBhbmQgUHJvIE1heCBhcmUgYXZhaWxhYmxlIGluOiBhbHBpbmUgZ3JlZW4sIHNpbHZlciwgZ29sZCwgZ3JhcGhpdGUsIHNpZXJyYSBibHVlLiBUaGUgaVBob25lIFNFIGlzIGF2YWlsYWJsZSBpbjogbWlkbmlnaHQsIHN0YXJsaWdodCwgcmVkIChbQXBwbGVdKGh0dHBzOi8vd3d3LmFwcGxlLmNvbS9pcGhvbmUvKSkuCgpBcHBsZSBhZHZlcnRpc2VzIHRoZSBpUGhvbmUgUHJvIHdpdGggdGhlIGZvbGxvd2luZyBmZWF0dXJlczoKCi0gICAiQSBkcmFtYXRpY2FsbHkgbW9yZSBwb3dlcmZ1bCBjYW1lcmEgc3lzdGVtLgoKLSAgIEEgZGlzcGxheSBzbyByZXNwb25zaXZlLCBldmVyeSBpbnRlcmFjdGlvbiBmZWVscyBuZXcgYWdhaW4uCgotICAgVGhlIHdvcmxkJ3MgZmFzdGVzdCBzbWFydHBob25lIGNoaXAuCgotICAgRXhjZXB0aW9uYWwgZHVyYWJpbGl0eS4KCi0gICBBbmQgYSBodWdlIGxlYXAgaW4gYmF0dGVyeSBsaWZlLiIgKFtTYW1zdW5nXShodHRwczovL3d3dy5hcHBsZS5jb20vaXBob25lLTEzLXByby8pKQoKWyFbXShodHRwczovL3d3dy5hcHBsZS5jb20vbmV3c3Jvb20vaW1hZ2VzL3Byb2R1Y3QvaXBob25lL3N0YW5kYXJkL0FwcGxlLWlQaG9uZTEzLVByby1jb2xvci1saW5ldXAtMjIwMzA4X2JpZ19jYXJvdXNlbC5qcGcuc21hbGxfMnguanBnICJBcHBsZSBpUGhvbmUgMTMiKXt3aWR0aD0iNzE0In1dKGh0dHBzOi8vZW5jcnlwdGVkLXRibjAuZ3N0YXRpYy5jb20vaW1hZ2VzP3E9dGJuOkFOZDlHY1JWN1pjN1hwVEVSOGphX1BydHVJeHFzYXBqczAxRWxzdXFLUSZ1c3FwPUNBVSkKCltQaWN0dXJlIFNvdXJjZV0oaHR0cHM6Ly93d3cuYXBwbGUuY29tL25ld3Nyb29tL2ltYWdlcy9wcm9kdWN0L2lwaG9uZS9zdGFuZGFyZC9BcHBsZS1pUGhvbmUxMy1Qcm8tY29sb3ItbGluZXVwLTIyMDMwOF9iaWdfY2Fyb3VzZWwuanBnLnNsaWRlc2hvdy14bGFyZ2UuanBnKQoKIyMgQ29tcGFyaXNvbiBvZiBGZWF0dXJlcwoKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTYW1zdW5nIFMyMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEFwcGxlIGlQaG9uZSAxMyAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09Kz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0rPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKfCAqKlN0YXJ0aW5nIFByaWNlKiogICAgICAgICAgfCBcJDc5OSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFwkNzk5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKlNjcmVlbiBzaXplKiogICAgICAgICAgICAgfCA2LjEgaW5jaGVzICgyMzQwIHggMTA4MCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDYuMSBpbmNoZXMgKDI1MzIgeCAxMTcwKSAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKlJlZnJlc2ggcmF0ZSoqICAgICAgICAgICAgfCA0OEh6LTEyMEh6IGFkYXB0aXZlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDYwSHogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKkNQVSoqICAgICAgICAgICAgICAgICAgICAgfCBTbmFwZHJhZ29uIDggR2VuIDEgKFVTKTsgRXh5bm9zIDIyMDAgKEspICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEExNSBCaW9uaWMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKlJBTSoqICAgICAgICAgICAgICAgICAgICAgfCA4R0IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDRHQiAoYmFzZWQgb24gdGVhcmRvd25zKSAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKlN0b3JhZ2UqKiAgICAgICAgICAgICAgICAgfCAxMjhHQiwgMjU2R0IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDEyOEdCLCAyNTZHQiwgNTEyR0IgICAgICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKlJlYXIgY2FtZXJhcyoqICAgICAgICAgICAgfCA1ME1QIHdpZGUgKGYvMS44KTsgMTJNUCB1bHRyYXdpZGUgKGYvMi4yKTsgMTBNUCB0ZWxlcGhvdG8gKGYvMi40KSB3aXRoIDN4IG9wdGljYWwgem9vbSB8IDEyTVAgbWFpbiAoZi8xLjYpLCAxMk1QIHVsdHJhd2lkZSAoZi8yLjQpIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKkZyb250IGNhbWVyYSoqICAgICAgICAgICAgfCAxME1QIChmLzIuMikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDEyTVAgKGYvMi4yKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKkJhdHRlcnkgc2l6ZSoqICAgICAgICAgICAgfCAzLDcwMCBtQWggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDMsMjI3IG1BaCAoYmFzZWQgb24gdGVhcmRvd25zKSAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKkJhdHRlcnkgbGlmZSAoSHJzOk1pbnMpKiogfCA3OjUxICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDEwOjMzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKkNoYXJnaW5nIHNwZWVkcyoqICAgICAgICAgfCAyNVcgd2lyZWQsIDE1VyB3aXJlbGVzcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDIwVyB3aXJlZDsgMTVXIHdpcmVsZXNzICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKlNpemUqKiAgICAgICAgICAgICAgICAgICAgfCA1LjcgeCAyLjggeCAwLjMgaW5jaGVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDUuOCB4IDIuOCB4IDAuMyBpbmNoZXMgICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKldlaWdodCoqICAgICAgICAgICAgICAgICAgfCA1Ljkgb3VuY2VzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDYuMTQgb3VuY2VzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCAqKkNvbG9ycyoqICAgICAgICAgICAgICAgICAgfCBCbGFjaywgd2hpdGUsIGdyZWVuLCBwaW5rIGdvbGQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEJsYWNrLCB3aGl0ZSwgYmx1ZSwgcGluaywgcmVkLCBncmVlbiAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKClNvdXJjZTogPGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vZmFjZS1vZmYvc2Ftc3VuZy1nYWxheHktczIyLXZzLWlwaG9uZS0xMz4KCiMjIE9iamVjdGl2ZXMgb2Ygb3VyIFJlc2VhcmNoCgotICAgSWRlbnRpZmljYXRpb24gb2YgdGhlIHN0cmVuZ3RocyBhbmQgd2Vha25lc3NlcyBvZiB0aGUgY29tcGV0aXRvcnMgd2hpY2ggY2FuIGhlbHAgdG8gaWRlbnRpZnkgYSBnYXAgaW4gYSBtYXJrZXQgYW5kIGVuaGFuY2luZyB0aGUgb3duIGJ1c2luZXNzIHN0cmF0ZWd5LgoKLSAgIElkZW50aWZpY2F0aW9uIG9mIHN1Z2dlc3Rpb25zIHRvIGN1c3RvbWVycyBhYm91dCB0aGUgcHJvZHVjdHMgYmFzZWQgb24gb3RoZXIgY3VzdG9tZXJzJyBvcGluaW9ucwoKIyMgTWV0aG9kb2xvZ3kgb2Ygb3VyIFJlc2VhcmNoCgojIFR3aXR0ZXIgQW5hbHlzaXMKCmBgYHtyIEluaXRpYWxpc2luZyBQYWNrYWdlcywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShiYXNlNjRlbmMpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdncmFwaCkKbGlicmFyeShodHRwdXYpCmxpYnJhcnkoaHR0cikKbGlicmFyeShpZ3JhcGgpCmxpYnJhcnkob3BlbnNzbCkKbGlicmFyeShwbHlyKQpsaWJyYXJ5KFJDdXJsKQpsaWJyYXJ5KFJPQXV0aCkKbGlicmFyeShydHdlZXQpCmxpYnJhcnkoc2VudGltZW50cikKbGlicmFyeShTbm93YmFsbEMpCmxpYnJhcnkoc3RvcHdvcmRzKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkoc3l1emhldCkKbGlicmFyeSh0ZXh0Y2xlYW4pCmxpYnJhcnkodGV4dG1pbmVSKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KHRpZHl0ZXh0KQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeSh0bSkKbGlicmFyeSh0b3BpY21vZGVscykKbGlicmFyeSh0d2l0dGVSKQpsaWJyYXJ5KHdpZHlyKQpsaWJyYXJ5KHdvcmRjbG91ZCkKYGBgCgpgYGB7ciBTZXR1cCB0d2l0dGVyLCBpbmNsdWRlPUZBTFNFfQojIyMjIHNldHRpbmcgdGhlIHdvcmtpbmcgZGlyZWN0b3J5ICMjIyMKI3NldHdkKCIvVXNlcnMvTGlseS9MaWJyYXJ5L01vYmlsZSBEb2N1bWVudHMvY29tfmFwcGxlfkNsb3VkRG9jcy9UcmluaXR5IENvbGxlZ2UgRHVibGluL0JVNzE0NyBTb2NpYWwgTWVkaWEgQW5hbHlzaXMvR3JvdXAgQXNzaWdubWVudC9Tb2NpYWwtTWVkaWEtQW5hbHl0aWNzIikKCiMjIyMgaW5pdGlhbGl6aW5nIGtleXMgIyMjIwojYmVhcmVyX3Rva2VuPC0iIyMjIyMjIyIKI2NvbnN1bWVyX2tleTwtIiMjIyMjIyMiCiNjb25zdW1lcl9zZWNyZXQ8LSIjIyMjIyMjIgojYWNjZXNzX3Rva2VuPC0iIyMjIyMjIyIKI2FjY2Vzc190b2tlbl9zZWNyZXQ8LSIjIyMjIyMjIgoKI3NldHVwX3R3aXR0ZXJfb2F1dGgoY29uc3VtZXJfa2V5PWNvbnN1bWVyX2tleSwKICAgICAgICAgICAgICAgICAgICAjIGNvbnN1bWVyX3NlY3JldD1jb25zdW1lcl9zZWNyZXQsCiAgICAgICAgICAgICAgICAgICAgIyBhY2Nlc3NfdG9rZW49YWNjZXNzX3Rva2VuLAogICAgICAgICAgICAgICAgICAgICMgYWNjZXNzX3NlY3JldD1hY2Nlc3NfdG9rZW5fc2VjcmV0KQpgYGAKCiMjIERhdGEgRXh0cmFjdGlvbiBhbmQgQ2xlYW5pbmcKCiMjIyBTYW1zdW5nIFMyMgoKV2UgZGVjaWRlZCB0byBleHRyYWN0IGRhdGEgZnJvbSBUd2l0dGVyIHdpdGggdGhlIGtleXdvcmRzICJTYW1zdW5nIFMyMiIgYW5kIHRoZSBoYXNodGFnICJcI3NhbXN1bmdzMjIiIGZyb20gMzEuMDMuMjAyMiAtIDA4LjA0LjIwMjIgYXMgd2UgZG8gbm90IGhhdmUgYSBwcmVtaXVtIGxpY2Vuc2UgdG8gZ2V0IGFjY2VzcyB0byB0aGUgZnVsbCB0aW1lbGluZSBvZiB0d2VldHMgb24gdGhlIFR3aXR0ZXJBUEkuCgpXZSBleGNsdWRlZCBmcm9tIG91ciBxdWVyeSB0aGUgdXNlcnMgU2hvcGVlSUQsIFxfYXJsbGVlIGFuZCBhbGwgcmV0d2VldHMgZm9yIHRoZSBrZXl3b3JkcyAiU2Ftc3VuZyBTMjIiIGJlY2F1c2UgdGhlcmUgd2VyZSBtdWx0aXBsZSB0aG91c2FuZHMgb2YgdHdlZXRzIGFib3V0IGEgY29tcGV0aXRpb24gdG8gd2luIGEgU2Ftc3VuZyBtb2JpbGUgcGhvbmUgd2hpY2ggY2F1c2VkIGEgbG90IG9mIGR1cGxpY2F0ZWQgZGF0YS4KCkFzIHdlbGwsIHdlIGlkZW50aWZpZWQgbmluZSB1c2VycyB3aGljaCB3ZXJlIGNyZWF0aW5nIGFkdmVydGlzaW5nIHNwYW0gYW5kIG5vbi12YWx1YWJsZSB0d2VldHMgdGhhdCB3ZSBoYWQgdG8gZXhjbHVkZTogIndoaXRlc3RvbmVkb21lIiwgIkZyb21Lb3JlYTUiLCAiZG9tZV9nbGFzcyIsICJXaGl0ZXN0b25lX0RFIiwgIndoaXRlc3RvbmVfVUsiLCAianBfd2hpdGVzdG9uZSIsICJXaGl0ZXN0b25lXF9cX0ZSIiwgIldoaXRlc3RvbmVKYXBhbiIsICJXaGl0ZXN0b25lRVUiLgoKSW4gdG90YWwgd2UgY291bGQgZ2F0aGVyIDM4NDYgdHdlZXRzLgoKYGBge3IgRXh0cmFjdGluZyBUd2VldHMgYWJvdXQgU2Ftc3VuZyBmcm9tIFR3aXR0ZXIsIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMjIyMgR2V0dGluZyBUd2VldHMgYWJvdXQgU2Ftc3VuZyAjIyMjCiMgc3R3ZWV0czEgPC0gc2VhcmNoVHdpdHRlcigiI3NhbXN1bmdzMjIgLWZpbHRlcjpyZXR3ZWV0cyIsIG49MTAwMDAsIGxhbmc9ImVuIiwgcmV0cnlPblJhdGVMaW1pdCA9IDEwMCkKIyBzZGYxIDwtIHR3TGlzdFRvREYoc3R3ZWV0czEpCiMgVmlldyhzZGYxKQojIAojIHN0d2VldHMyIDwtIHNlYXJjaFR3aXR0ZXIoIlNhbXN1bmcgKyBTMjIgLUBTaG9wZWVJRCAtQF9hcmxsZWUgLWZpbHRlcjpyZXR3ZWV0cyIsIG49MTAwMDAsIGxhbmc9ImVuIiwgcmV0cnlPblJhdGVMaW1pdCA9IDEwMCkKIyBzZGYyIDwtIHR3TGlzdFRvREYoc3R3ZWV0czIpCiMgVmlldyhzZGYyKQojIAojIHNkMl91c2VycyA8LSBzZGYyICU+JQojICAgZGlzdGluY3Qoc2NyZWVuTmFtZSwgaWQpICU+JQojICAgZ3JvdXBfYnkoc2NyZWVuTmFtZSkgJT4lCiMgICBzdW1tYXJpc2UoIm51bWJlciBvZiB0d2VldHMiID0gbigpKQojIFZpZXcoc2QyX3VzZXJzKQojIHN1bShzZDJfdXNlcnMkYG51bWJlciBvZiB0d2VldHNgKQojIAojIGFkX3R3ZWV0cyA8LSBjKCJ3aGl0ZXN0b25lZG9tZSIsICJGcm9tS29yZWE1IiwgImRvbWVfZ2xhc3MiLCAiV2hpdGVzdG9uZV9ERSIsICJ3aGl0ZXN0b25lX1VLIiwgImpwX3doaXRlc3RvbmUiLCAiV2hpdGVzdG9uZV9fRlIiLCAiV2hpdGVzdG9uZUphcGFuIiwgIldoaXRlc3RvbmVFVSIpCiMgCiMgc2RmMl9maWx0ZXIgPC0gc2RmMiAlPiUKIyAgIGZpbHRlcighc2NyZWVuTmFtZSAlaW4lIGFkX3R3ZWV0cykKIyBWaWV3KHNkZjJfZmlsdGVyKQojIAojIHNkMl91c2VyczIgPC0gc2RmMl9maWx0ZXIgJT4lCiMgICBkaXN0aW5jdChzY3JlZW5OYW1lLCBpZCkgJT4lCiMgICBncm91cF9ieShzY3JlZW5OYW1lKSAlPiUKIyAgIHN1bW1hcmlzZSgibnVtYmVyIG9mIHR3ZWV0cyIgPSBuKCkpCiMgVmlldyhzZDJfdXNlcnMyKQojIAojIHNhbXN1bmdfZGYgPC0gcmJpbmQoc2RmMSwgc2RmMl9maWx0ZXIpCiMgVmlldyhzYW1zdW5nX2RmKQojIHdyaXRlLmNzdihzYW1zdW5nX2RmLCJTYW1zdW5nX2RmLmNzdiIpCmBgYAoKT3VyIGluaXRpYWwgZGF0YSBmcmFtZSBoYXMgMTcgYXR0cmlidXRlcy4gWW91IGNhbiBmaW5kIHRoZSBtZWFuaW5nIG9mIGVhY2ggb2YgdGhlIGF0dHJpYnV0ZXMgaGVyZSBvbiB0aGUgW1R3aXR0ZXIgRGV2ZWxvcGVyIFBsYXRmb3JtXShodHRwczovL2RldmVsb3Blci50d2l0dGVyLmNvbS9lbi9kb2NzL3R3aXR0ZXItYXBpL3YxL2RhdGEtZGljdGlvbmFyeS9vYmplY3QtbW9kZWwvdHdlZXQpLgoKYGBge3IgU2Ftc3VuZyBSZWFkIERhdGEsIGVjaG89RkFMU0V9CiMjIyMjIFNhbXN1bmc6IFVzZSB0aGlzIGRhdGFmcmFtZSBmcm9tIG5vdyBvbiBzbyB3ZSB3b3JrIG9uIHNhbWUgZGF0YSAjIyMjIwpzYW1zdW5nX2RmIDwtIHJlYWQuY3N2KCJTYW1zdW5nX2RmLmNzdiIpCmhlYWQoc2Ftc3VuZ19kZikKYGBgCgpJbiB0aGUgZm9sbG93aW5nIGNvZGUgd2UgY2hlY2tlZCB0aGF0IHRoZSBkYXRhLmZyYW1lIHdhcyBjb3JyZWN0bHkgZm9ybWF0dGVkOgoKYGBge3IgU2Ftc3VuZyBEYXRhIFN0cnVjdHVyZSwgZWNobz1GQUxTRX0Kc3RyKHNhbXN1bmdfZGYpCmBgYAoKIyMjIEFwcGxlIGlQaG9uZSAxMwoKV2UgZXh0cmFjdGVkIGRhdGEgZm9yIHRoZSBzZWFyY2ggdGVybXMgImlQaG9uZSAxMyIgZXhjbHVkaW5nIHJldHdlZXRzIGFuZCB0aGUgaGFzaHRhZyAiXCNpcGhvbmUxMyIgZnJvbSB0aGUgVHdpdHRlckFQSS4gU2ltaWxhcmx5LCB0byB0aGUgU2Ftc3VuZyBTMjIgd2UgaGFkIHRvIGV4Y2x1ZGUgY2VydGFpbiB1c2VycyB3aGljaCB3ZXJlIGFkdmVydGlzaW5nICgid2hpdGVzdG9uZWRvbWUiLCAiRnJvbUtvcmVhNSIsICJkb21lZ2xhc3NhcHBsZSIpIGFuZCBjb21wZXRpdGlvbnMgdG8gd2luIGFuIGlQaG9uZSB3aGVuIHJldHdlZXRpbmcgb3IgY29weS1wYXN0aW5nIGEgc3BlY2lmaWMgdGV4dCAoIkpvaW4gdGhlIGV2ZW50IHRvIHdpbiBhbiBpUGhvbmUgMTMhIikuIEFsc28sIHdlIGhhZCBhIGhpZ2ggbnVtYmVyIG9mIHR3ZWV0cyB3aGljaCB3ZXJlIHJhbmRvbWx5IHBvc3RpbmcgYnJhbmQgbmFtZXMsIGUuZy4gInJvbGV4IGlwaG9uZSIgaW4gb25lIHR3ZWV0LgoKSW4gdG90YWwgd2UgY291bGQgZ2F0aGVyIDgzNjkgdHdlZXRzLgoKYGBge3IgRXh0cmFjdGluZyBUd2VldHMgYWJvdXQgQXBwbGUgZnJvbSBUd2l0dGVyLCBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQojIyMjIEdldHRpbmcgVHdlZXRzIGFib3V0IEFwcGxlICMjIyMKIyBhdHdlZXRzMSA8LSBzZWFyY2hUd2l0dGVyKCJpUGhvbmUgKyAxMyAtZmlsdGVyOnJldHdlZXRzIiwgbj0xMDAwMCwgbGFuZz0iZW4iLCByZXRyeU9uUmF0ZUxpbWl0ID0gMTAwKQojIGFkZjEgPC0gdHdMaXN0VG9ERihhdHdlZXRzMSkKIyBWaWV3KGFkZjEpCiMgCiMgYWRmX3VzZXJzIDwtIGFkZjEgJT4lCiMgICBkaXN0aW5jdChzY3JlZW5OYW1lLCBpZCkgJT4lCiMgICBncm91cF9ieShzY3JlZW5OYW1lKSAlPiUKIyAgIHN1bW1hcmlzZSgibnVtYmVyIG9mIHR3ZWV0cyIgPSBuKCkpCiMgVmlldyhhZGZfdXNlcnMpCiMgCiMgYWRmX3JlcGxpZXMgPC0gYWRmMSAlPiUKIyAgIGRpc3RpbmN0KHJlcGx5VG9TTiwgaWQpICU+JQojICAgZ3JvdXBfYnkocmVwbHlUb1NOKSAlPiUKIyAgIHN1bW1hcmlzZSgibnVtYmVyIG9mIHJlcGxpZXMgdG8gdXNlciIgPSBuKCkpCiMgVmlldyhhZGZfcmVwbGllcykKIyAKIyBhcHBsZV9hZF90d2VldHMgPC0gYygid2hpdGVzdG9uZWRvbWUiLCAiRnJvbUtvcmVhNSIsICJkb21lZ2xhc3NhcHBsZSIpCiMgCiMgYWRmX2ZpbHRlciA8LSBhZGYxICU+JQojICAgZmlsdGVyKCFzY3JlZW5OYW1lICVpbiUgYXBwbGVfYWRfdHdlZXRzKQojIFZpZXcoYWRmX2ZpbHRlcikKIyAKIyBhdHdlZXRzMiA8LSBzZWFyY2hUd2l0dGVyKCIjaXBob25lMTMgLWZpbHRlcjpyZXR3ZWV0cyIsIG49MTAwMDAsIGxhbmc9ImVuIiwgcmV0cnlPblJhdGVMaW1pdCA9IDEwMCkKIyBhZGYyIDwtIHR3TGlzdFRvREYoYXR3ZWV0czIpCiMgVmlldyhhZGYyKQojIAojIGFkZl91c2VyczIgPC0gYWRmMiAlPiUKIyAgIGRpc3RpbmN0KHNjcmVlbk5hbWUsIGlkKSAlPiUKIyAgIGdyb3VwX2J5KHNjcmVlbk5hbWUpICU+JQojICAgc3VtbWFyaXNlKCJudW1iZXIgb2YgdHdlZXRzIiA9IG4oKSkKIyBWaWV3KGFkZl91c2VyczIpCiMgCiMgYWRmX3JlcGxpZXMyIDwtIGFkZjIgJT4lCiMgICBkaXN0aW5jdChyZXBseVRvU04sIGlkKSAlPiUKIyAgIGdyb3VwX2J5KHJlcGx5VG9TTikgJT4lCiMgICBzdW1tYXJpc2UoIm51bWJlciBvZiByZXBsaWVzIHRvIHVzZXIiID0gbigpKQojIFZpZXcoYWRmX3JlcGxpZXMpCiMgCiMgYXBwbGVfZGYgPC0gcmJpbmQoYWRmX2ZpbHRlciwgYWRmMikKIyAKIyAjdGhlcmUgaXMgYW5vdGhlciBjb21wZXRpdGlvbiB3aGljaCBkaWQgbm90IG5lZWQgcmV0d2VldHMgb3IgcmVwbHlpbmcgdG8gc29tZW9uZSBzcGVjaWZpY2FsbHkgCiMgI3Blb3BsZSBjb3BpZWQgdGhlIHRleHQgdG8gdGFrZSBwYXJ0LCB0aGVyZWZvcmUsIHRoZSB3b3JkICJ0cmVhc3VyZSIgYW5kICJ3aW4iIHdlcmUgZXhvcmJpdGFudCBpbiBvdXIgYW5hbHlzaXMKIyAjdGhlcmVmb3JlIHdlIGV4Y2x1ZGVkIGFsbCByb3dzIHRoYXQgaGFkIHRoaXMgdGV4dAojIGFwcGxlX2RmIDwtIGFwcGxlX2RmICU+JQojICAgZmlsdGVyKCFncmVwbCgiSm9pbiB0aGUgZXZlbnQgdG8gd2luIGFuIGlQaG9uZSAxMyEiLHRleHQpKSAgJT4lCiMgICBmaWx0ZXIoIWdyZXBsKCJyb2xleCIsdGV4dCkpCiMgCiMgd3JpdGUuY3N2KGFwcGxlX2RmLCJBcHBsZV9kZi5jc3YiKQpgYGAKCk91ciBpbml0aWFsIGRhdGEgZnJhbWUgaGFzIDE3IGF0dHJpYnV0ZXMuIFlvdSBjYW4gZmluZCB0aGUgbWVhbmluZyBvZiBlYWNoIG9mIHRoZSBhdHRyaWJ1dGVzIGhlcmUgb24gdGhlIFtUd2l0dGVyIERldmVsb3BlciBQbGF0Zm9ybV0oaHR0cHM6Ly9kZXZlbG9wZXIudHdpdHRlci5jb20vZW4vZG9jcy90d2l0dGVyLWFwaS92MS9kYXRhLWRpY3Rpb25hcnkvb2JqZWN0LW1vZGVsL3R3ZWV0KS4KCmBgYHtyIEFwcGxlIFJlYWQgRGF0YSwgZWNobz1GQUxTRX0KIyMjIyMgQXBwbGU6IFVzZSB0aGlzIGRhdGFmcmFtZSBmcm9tIG5vdyBvbiBzbyB3ZSB3b3JrIG9uIHNhbWUgZGF0YSAjIyMjIwphcHBsZV9kZiA8LSByZWFkLmNzdigiQXBwbGVfZGYuY3N2IikKaGVhZChhcHBsZV9kZikKCmBgYAoKSW4gdGhlIGZvbGxvd2luZyBjb2RlIHdlIGNoZWNrZWQgdGhhdCB0aGUgZGF0YS5mcmFtZSB3YXMgY29ycmVjdGx5IGZvcm1hdHRlZDoKCmBgYHtyIEFwcGxlIERhdGEgU3RydWN0dXJlLCBlY2hvPUZBTFNFfQpzdHIoYXBwbGVfZGYpCmBgYAoKIyMgSG93IE1hbnkgVXNlcnMgV2VyZSBQb3N0aW5nIEhvdyBNYW55IFR3ZWV0cyBpbiB0aGUgRGF0YXNldD8KCmBgYHtyIFN0YXRpc3RpY3MgU2Ftc3VuZywgaW5jbHVkZT1GQUxTRX0Kc3RhdHNfcyA8LSBzYW1zdW5nX2RmICU+JQogIG11dGF0ZShkYXRlID0gc3Vic3RyKGNyZWF0ZWQsMSwxMCkpCnN0YXRzX3MgPC0gYWdncmVnYXRlKGNiaW5kKGNvdW50X3VzZXJzID0gc2NyZWVuTmFtZSwgY291bnRfdHdlZXRzID0gaWQpIH4gZGF0ZSwgCiAgICAgICAgICBkYXRhID0gc3RhdHNfcywgCiAgICAgICAgICBGVU4gPSBmdW5jdGlvbih4KXtuX2Rpc3RpbmN0KHgpfSkKc3RhdHNfcyA8LSBzdGF0c19zICU+JQogIG11dGF0ZShhdmdfdHdlZXRzX3Blcl91c2VyID0gY291bnRfdHdlZXRzIC8gY291bnRfdXNlcnMpICU+JQogIG11dGF0ZSh3ZWVrZGF5ID0gd2Vla2RheXMoYXMuRGF0ZShkYXRlKSkpCnN0YXRzX3MgPC0gZGF0YS5mcmFtZShzdGF0c19zKQpzdGF0c19zCmBgYAoKYGBge3IgU3RhdGlzdGljcywgaW5jbHVkZT1GQUxTRX0Kc3RhdHNfYSA8LSBhcHBsZV9kZiAlPiUKICBtdXRhdGUoZGF0ZSA9IHN1YnN0cihjcmVhdGVkLDEsMTApKQpzdGF0c19hIDwtIGFnZ3JlZ2F0ZShjYmluZChjb3VudF91c2VycyA9IHNjcmVlbk5hbWUsIGNvdW50X3R3ZWV0cyA9IGlkKSB+IGRhdGUsIAogICAgICAgICAgICAgICAgICAgICBkYXRhID0gc3RhdHNfYSwgCiAgICAgICAgICAgICAgICAgICAgIEZVTiA9IGZ1bmN0aW9uKHgpe25fZGlzdGluY3QoeCl9KQpzdGF0c19hIDwtIHN0YXRzX2EgJT4lCiAgbXV0YXRlKGF2Z190d2VldHNfcGVyX3VzZXIgPSBjb3VudF90d2VldHMgLyBjb3VudF91c2VycykgJT4lCiAgbXV0YXRlKHdlZWtkYXkgPSB3ZWVrZGF5cyhhcy5EYXRlKGRhdGUpKSkKc3RhdHNfYSA8LSBkYXRhLmZyYW1lKHN0YXRzX2EpCnN0YXRzX2EKYGBgCgpXaGlsZSB0aGVyZSB3ZXJlIG9ubHkgMzg0NiB0d2VldHMgZnJvbSB1c2VycyBhYm91dCB0aGUgU2Ftc3VuZyBTMjIsIHRoZXJlIHdlcmUgMi4xNyB0aW1lcyBtb3JlIHR3ZWV0cyBhYm91dCB0aGUgQXBwbGUgaVBob25lIDEzIGR1cmluZyB0aGUgcGVyaW9kIGNvbnNpZGVyZWQuCgpgYGB7ciBTdGF0cywgZWNobz1GQUxTRX0KZ2dwbG90KCkgKyAKICBnZW9tX2xpbmUoZGF0YT1zdGF0c19zLCBhZXMoeD1kYXRlLCB5ID0gY291bnRfdHdlZXRzLCBjb2xvciA9ICJTYW1zdW5nIFMyMiIsIGdyb3VwID0gMSkpICsgCiAgZ2VvbV9saW5lKGRhdGE9c3RhdHNfYSwgYWVzKHg9ZGF0ZSwgeSA9IGNvdW50X3R3ZWV0cywgY29sb3IgPSAiQXBwbGUgaVBob25lIDEzIiwgZ3JvdXAgPSAxKSkgKwogIGdlb21fcG9pbnQoZGF0YT1zdGF0c19zLCBhZXMoeD1kYXRlLCB5PWNvdW50X3VzZXJzLCBjb2xvciA9IlNhbXN1bmcgUzIyIiwgZ3JvdXA9MSkpKwogIGdlb21fcG9pbnQoZGF0YT1zdGF0c19hLCBhZXMoeD1kYXRlLCB5PWNvdW50X3VzZXJzLCBjb2xvciA9IkFwcGxlIGlQaG9uZSAxMyIsIGdyb3VwPTEpKSArCiAgeWxhYigiTnVtYmVyIG9mIFR3ZWV0cyBvciBVc2VycyIpICsKICB4bGFiKCJkYXRlIikgKwogIGdndGl0bGUoIlRoZSBOdW1iZXIgb2YgVXNlcnMgKHBvaW50cykgYW5kIFR3ZWV0cyAobGluZSkgb3ZlciBUaW1lIikKYGBgCgpPbiAzIG91dCBvZiA5IGRheXMgU2Ftc3VuZyBTMjIgaGFkIG1vcmUgdHdlZXRzIHRoYW4gaVBob25lIDEzLiBPbiB0aGUgb3RoZXIgZGF5cyBBcHBsZSBleGNlZWRlZCB0aGUgbnVtYmVyIG9mIHR3ZWV0cyBleHRyZW1lbHkuIFN1cnByaXNpbmdseSwgdGhlIG51bWJlciBvZiB0d2VldHMgYW5kIHVzZXJzIHBlciBkYXkgZm9yIHRoZSBTYW1zdW5nIFMyMiByZW1haW5zIGNvbnN0YW50IHdoaWxlIHRoZXJlIGFyZSBvbmx5IGEgZmV3IHR3ZWV0cyBhYm91dCB0aGUgaVBob25lIDEzIGluIHRoZSBmaXJzdCAzIGRheXMgYW5kIGEgaGlnaCB2b2x1bWUgb2YgdHdlZXRzIGZyb20gM25kIEFwcmlsIHVudGlsIDd0aCBBcHJpbCAyMDIyLiBUaGVyZSB3YXMgbm90IG9ubHkgbW9yZSB0d2VldHMgYnV0IGFsc28gYSBsYXJnZXIgZ3JvdXAgb2YgdXNlcnMgcG9zdGluZyBhYm91dCBpUGhvbmUgMTMuIFdlIGNvdWxkIG5vdCBpZGVudGlmeSBhIHNwZWNpZmljIHJlYXNvbiBmb3IgdGhpcyBwaGVub21lbm9uIGJlY2F1c2UgdGhlIGxhc3Qgb2ZmaWNpYWwgQXBwbGUgZXZlbnQgd2FzIGluIE1hcmNoIDIwMjIgYW5kIG5vdCBpbiB0aGUgdGltZSBwZXJpb2Qgd2UgdGVzdGVkLgoKVGhlcmUgaXMgbm8gc2ltaWxhciBpbmRpY2F0b3IgZnJvbSBbR29vZ2xlIFRyZW5kc10oaHR0cHM6Ly90cmVuZHMuZ29vZ2xlLmNvbS90cmVuZHMvZXhwbG9yZT9kYXRlPTIwMjItMDMtMzElMjAyMDIyLTA0LTA4JnE9aVBob25lJTIwMTMsU2Ftc3VuZyUyMFMyMixBcHBsZSxTYW1zdW5nKSBvciBvdGhlciBzb3VyY2VzLiBUaGUgc2VhcmNoIHRlcm1zIGlQaG9uZSAxMywgU2Ftc3VuZyBTMjIsIEFwcGxlIGFuZCBTYW1zdW5nIGFyZSByZWxhdGl2ZWx5IGNvbnN0YW50IG92ZXIgdGltZSBhcyB5b3UgY2FuIHNlZSBmcm9tIHRoZSBpbWFnZSBiZWxvdyAoU2NyZWVuc2hvdCBmcm9tIEdvb2dsZSBUcmVuZHMpLiBJdCBjYW4gYmUgbm90ZWQgdGhhdCBBcHBsZSBpcyBtb3JlIGxpa2VseSB0byBiZSBsb29rZWQgdXAgdGhhbiBTYW1zdW5nIGFzIHdlbGwgYXMgdGhlIGlQaG9uZSAxMyBpcyBtb3JlIHBvcHVsYXIgb24gR29vZ2xlIFNlYXJjaCB0aGFuIFNhbXN1bmcgUzIyLiBUaGlzIGdpdmVzIHVzIGEgZmlyc3QgaW1wcmVzc2lvbiB0aGF0IHRoZSBpUGhvbmUgMTMgbW9kZWwgcmVjZWl2ZXMgaW4gZ2VuZXJhbCBtb3JlIGF0dGVudGlvbi4KCiFbXShpbWFnZXMvcGFzdGUtMkQ1MDA0QzIucG5nKQoKVGhlcmUgYXJlIG1vcmUgdHdlZXRzIHRoYW4gdXNlcnMgd2hpY2ggaW5kaWNhdGVzIHRoYXQgc29tZSB1c2VycyB1c3VhbGx5IHBvc3QgbW9yZSB0aGFuIG9uZSB0d2VldC4gV2UgY2FsY3VsYXRlZCBhIHJhdGlvIGZvciB0aGlzOiBgYXZnX3R3ZWV0c19wZXJfdXNlciA9IHR3ZWV0cyBwZXIgZGF5IC8gdXNlcnMgcGVyIGRheWAuCgpgYGB7ciBVc2VyIFR3ZWV0aW5nIEJlaGF2aW91ciwgZWNobz1GQUxTRX0KY29tcF90d19wX3UgPC0gZGF0YS5mcmFtZShkYXRlPXBhc3RlKGRhdGU9c3Vic3RyKHN0YXRzX2EkZGF0ZSw2LDEwKSwgd2Vla2RheT1zdGF0c19hJHdlZWtkYXkpLCBzdGF0c19hJGF2Z190d2VldHNfcGVyX3VzZXIsIHN0YXRzX3MkYXZnX3R3ZWV0c19wZXJfdXNlcikKZ2dwbG90KCkrCiAgZ2VvbV9saW5lKGRhdGE9Y29tcF90d19wX3UsIGFlcyh4PWRhdGUsIHk9c3RhdHNfYS5hdmdfdHdlZXRzX3Blcl91c2VyLCBncm91cD0xLCBjb2xvcj0iQXBwbGUiKSkrIAogIGdlb21fbGluZShkYXRhPWNvbXBfdHdfcF91LCBhZXMoeD1kYXRlLCB5PXN0YXRzX3MuYXZnX3R3ZWV0c19wZXJfdXNlciwgZ3JvdXA9MSwgY29sb3I9IlNhbXN1bmciKSkrCiAgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA1KSkrCiAgeWxhYigiQXZlcmFnZSB0d2VldCBwZXIgdXNlciIpCmBgYAoKSXQgaXMgaW50ZXJlc3RpbmcgdGhvdWdoIHRoZXJlIHdlcmUgbGVzcyBjb252ZXJzYXRpb24gYWJvdXQgQXBwbGUgaW4gdGhlIGZpcnN0IHRocmVlIGRheXMsIHRoZXJlIHdlcmUgc3RhdGlzdGljYWxseSBtb3JlIHBlb3BsZSBpbnZvbHZlZCwgc28gaXQgc2VlbXMgdG8gYmUgYSBjb252ZXJzYXRpb24gYmV0d2VlbiBhIHNtYWxsZXIgZ3JvdXAgb2YgdXNlcnMuIFdlIHNlZSB0aGUgc2FtZSBmb3IgU2Ftc3VuZyBTMjIgYmV0d2VlbiA0dGggQXByaWwgdG8gNnRoIEFwcmlsIDIwMjIuCgojIyBXb3JkY2xvdWQKCiMjIyBEYXRhIFByZXByb2Nlc3NpbmcKCldlIGRlY2lkZWQgdG8gcHJlcHJvY2VzcyB0aGUgZGF0YSBiYXNlZCBvbiB0aGUgZm9sbG93aW5nIHN0ZXBzOgoKLSAgIEFsbCB0ZXh0IHdhcyBjb252ZXJ0ZWQgdG8gbG93ZXIgY2FzZSwgZS5nLiBIZWxsbyB0byBoZWxsby4KCi0gICBBbGwgY29udHJhY3Rpb25zIHdlcmUgY29udmVydGVkIHRvIHRoZSBsb25nZXIgZm9ybSwgZS5nLiBkb24ndCB0byBkbyBub3QKCi0gICBBbGwgY29tbW9uIGludGVybmV0IHNsYW5nIHdhcyBjb252ZXJ0ZWQgdG8gZm9ybWFsIEVuZ2xpc2gsIGUuZy4gVEdJRiB0byBUaGFua3MgR29kIGl0IGlzIEZyaWRheQoKLSAgIEhhc2h0YWdzIChcIykgd2VyZSByZW1vdmVkCgotICAgV29yZCBlbG9uZ2F0aW9uIHdhcyByZXBsYWNlZCB0byB0aGUgdXN1YWwgd29yZCBmb3JtLCBlLmcuIGhlZWVlZXkgdG8gaGV5CgotICAgQWxsIG5vbi1BU0NJSSBjaGFyYWN0ZXJzIHdlcmUgcmVwbGFjZWQgd2l0aCBlcXVpdmFsZW50IG9yIHJlbW92ZWQsICoqwqkqKiB0byAoQykKCi0gICBXaGl0ZSBzcGFjZSB3aXRoaW4gdGhlIHN0cmluZyBpcyByZWR1Y2VkIHRvIG9uZSB3aGl0ZSBzcGFjZQoKLSAgIFdoaXRlIHNwYWNlIGF0IHRoZSBzdGFydCBhbmQgZW5kIG9mIHRoZSBzdHJpbmcgd2FzIHJlbW92ZWQKCi0gICAiUlQiLCBpbXBsaWNhdGluZyB0aGF0IGl0cyBhIHJldHdlZXQgd2FzIHJlbW92ZWQKCi0gICBhbGwgbGlua3Mgd2VyZSByZW1vdmVkIGJhc2VkIG9uIHRoZSBzdGFydCBvZiAiaHR0cCIKCi0gICBhbGwgQHVzZXJuYW1lIHdlcmUgcmVtb3ZlZAoKLSAgIHB1bmN0dWF0aW9uIHdlcmUgcmVtb3ZlZAoKLSAgIHN0b3Agd29yZHMgd2VyZSByZW1vdmVkIGJhc2VkIG9uIHRoZSBSZWdFeCBhcHByb2FjaAoKYGBge3IgV29yZGNsb3VkIEJhc2ljcywgaW5jbHVkZT1GQUxTRX0KIyMjIyMgYnVpbGRpbmcgd29yZGNsb3VkICMjIyMjCnBhbDwtIGJyZXdlci5wYWwoOCwiRGFyazIiKQpzdG9wd29yZHNfcmVnZXggPC0gcGFzdGUoc3RvcHdvcmRzKCdlbicpLCBjb2xsYXBzZSA9ICdcXGJ8XFxiJykKc3RvcHdvcmRzX3JlZ2V4IDwtIHBhc3RlMCgnXFxiJywgc3RvcHdvcmRzX3JlZ2V4LCAnXFxiJykKYGBgCgpgYGB7ciBTYW1zdW5nIFByZXByb2Nlc3NpbmcsIGluY2x1ZGU9RkFMU0V9CndvcmRfcyA8LSBzYW1zdW5nX2RmJHRleHQgJT4lCiAgc3RyX3RvX2xvd2VyKCkgJT4lICNhbGwgdGV4dCB0byBsb3dlciBjYXNlCiAgcmVwbGFjZV9jb250cmFjdGlvbigpICU+JSAjcmVwbGFjZXMgY29udHJhY3Rpb25zIHRvIGxvbmdlciBmb3JtCiAgcmVwbGFjZV9pbnRlcm5ldF9zbGFuZygpICU+JSAjcmVwbGFjZXMgY29tbW9uIGludGVybmV0IHNsYW5nCiAgcmVwbGFjZV9oYXNoKHJlcGxhY2VtZW50ID0gIiIpICU+JSAjcmVtb3ZlcyBoYXNodGFncwogIHJlcGxhY2Vfd29yZF9lbG9uZ2F0aW9uKCkgJT4lICNyZW1vdmVzIHdvcmQgZWxvbmdhdGlvbiwgZS5nLiAiaGVlZWVleSIgdG8gImhleSIKICAjcmVwbGFjZV9lbW9qaSgpICU+JSAjcmVwbGFjZXMgZW1vamlzIHdpdGggdGhlIHdvcmQgZm9ybSAjd2UgZWxpbWluYXRlIHRoaXMgZnJvbSB3b3JkIHByZXByb2Nlc3NpbmcgYmVjYXVzZSB3ZSBkb24ndCB3YW50IGVtb2ppIHdvcmRzIHRvIGJlIHdpdGhpbiB0aGUgd29yZCBjbG91ZAogICNyZXBsYWNlX2Vtb2ppX2lkZW50aWZpZXIoKSAlPiUgI3JlcGxhY2VzIGVtb2ppIGlkZW50aWZpZXJzIHRvIHdvcmQgZm9ybSAjd2UgZWxpbWluYXRlIHRoaXMgZnJvbSB3b3JkIHByZXByb2Nlc3NpbmcgYmVjYXVzZSB3ZSBkb24ndCB3YW50IGVtb2ppIHdvcmRzIHRvIGJlIHdpdGhpbiB0aGUgd29yZCBjbG91ZAogICNyZXBsYWNlX25vbl9hc2NpaSgpICU+JSAjcmVwbGFjZXMgY29tbW9uIG5vbi1BU0NJSSBjaGFyYWN0ZXJzLiAjd2UgZWxpbWluYXRlIHRoaXMgZnJvbSB3b3JkIHByZXByb2Nlc3NpbmcgYmVjYXVzZSB3ZSBkb24ndCB3YW50IGVtb2ppIHdvcmRzIHRvIGJlIHdpdGhpbiB0aGUgd29yZCBjbG91ZAogIHN0cl9zcXVpc2goKSAlPiUgI3JlZHVjZXMgcmVwZWF0ZWQgd2hpdGVzcGFjZSBpbnNpZGUgYSBzdHJpbmcKICBzdHJfdHJpbSgpICU+JSAjcmVtb3ZlcyB3aGl0ZXNwYWNlIGZyb20gc3RhcnQgYW5kIGVuZCBvZiBzdHJpbmcKICB7Z3N1YigiKFJUfHZpYSkoKD86XFxiXFxXKkBcXHcrKSspIiwiIiwuKX0gJT4lICNyZW1vdmUgUlQgKHJldHdlZXRzKQogIHtnc3ViKCJodHRwW15bOmJsYW5rOl1dKyIsIiIsLil9ICU+JSAjcmVtb3ZlIGxpbmtzIHRoYXQgc3RhcnQgd2l0aCBodHRwCiAge2dzdWIoIkBcXHUrIiwiIiwuKX0gJT4lICNyZW1vdmUgbmFtZXMgCiAge2dzdWIoJ0BcXHcrJywgJycsIC4pfSAlPiUgIyByZW1vdmUgYXQgcGVvcGxlCiAge2dzdWIoIltbOnB1bmN0Ol1dIiwiICIsLil9ICU+JSNyZW1vdmUgcHVuY3R1YXRpb24KICB7Z3N1YigiW15bOmFsbnVtOl1dIiwiICIsLil9JT4lI3JlbW92ZSBwdW5jdHVhdGlvbgogIHJlbW92ZU51bWJlcnMoKSAlPiUKICByZW1vdmVXb3JkcyhzdG9wd29yZHMoImVuZ2xpc2giKSkgJT4lCiAgc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKHN0b3B3b3Jkc19yZWdleCwgJycpICU+JSAjcmVtb3ZlIHN0b3Agd29yZHMKICB1bmlxdWUoKSAjcmVtb3ZlIGR1cGxpY2F0ZXMKYGBgCgpgYGB7ciBBcHBsZSBQcmVwcm9jZXNzaW5nLCBpbmNsdWRlPUZBTFNFfQp3b3JkX2EgPC0gYXBwbGVfZGYkdGV4dCAlPiUKICBzdHJfdG9fbG93ZXIoKSAlPiUgI2FsbCB0ZXh0IHRvIGxvd2VyIGNhc2UKICByZXBsYWNlX2NvbnRyYWN0aW9uKCkgJT4lICNyZXBsYWNlcyBjb250cmFjdGlvbnMgdG8gbG9uZ2VyIGZvcm0KICByZXBsYWNlX2ludGVybmV0X3NsYW5nKCkgJT4lICNyZXBsYWNlcyBjb21tb24gaW50ZXJuZXQgc2xhbmcKICByZXBsYWNlX2hhc2gocmVwbGFjZW1lbnQgPSAiIikgJT4lICNyZW1vdmVzIGhhc2h0YWdzCiAgcmVwbGFjZV93b3JkX2Vsb25nYXRpb24oKSAlPiUgI3JlbW92ZXMgd29yZCBlbG9uZ2F0aW9uLCBlLmcuICJoZWVlZWV5IiB0byAiaGV5IgogICNyZXBsYWNlX2Vtb2ppKCkgJT4lICNyZXBsYWNlcyBlbW9qaXMgd2l0aCB0aGUgd29yZCBmb3JtICN3ZSBlbGltaW5hdGUgdGhpcyBmcm9tIHdvcmQgcHJlcHJvY2Vzc2luZyBiZWNhdXNlIHdlIGRvbid0IHdhbnQgZW1vamkgd29yZHMgdG8gYmUgd2l0aGluIHRoZSB3b3JkIGNsb3VkCiAgI3JlcGxhY2VfZW1vamlfaWRlbnRpZmllcigpICU+JSAjcmVwbGFjZXMgZW1vamkgaWRlbnRpZmllcnMgdG8gd29yZCBmb3JtICN3ZSBlbGltaW5hdGUgdGhpcyBmcm9tIHdvcmQgcHJlcHJvY2Vzc2luZyBiZWNhdXNlIHdlIGRvbid0IHdhbnQgZW1vamkgd29yZHMgdG8gYmUgd2l0aGluIHRoZSB3b3JkIGNsb3VkCiAgI3JlcGxhY2Vfbm9uX2FzY2lpKCkgJT4lICNyZXBsYWNlcyBjb21tb24gbm9uLUFTQ0lJIGNoYXJhY3RlcnMuICN3ZSBlbGltaW5hdGUgdGhpcyBmcm9tIHdvcmQgcHJlcHJvY2Vzc2luZyBiZWNhdXNlIHdlIGRvbid0IHdhbnQgZW1vamkgd29yZHMgdG8gYmUgd2l0aGluIHRoZSB3b3JkIGNsb3VkCiAgc3RyX3NxdWlzaCgpICU+JSAjcmVkdWNlcyByZXBlYXRlZCB3aGl0ZXNwYWNlIGluc2lkZSBhIHN0cmluZwogIHN0cl90cmltKCkgJT4lICNyZW1vdmVzIHdoaXRlc3BhY2UgZnJvbSBzdGFydCBhbmQgZW5kIG9mIHN0cmluZwogIHtnc3ViKCIoUlR8dmlhKSgoPzpcXGJcXFcqQFxcdyspKykiLCIiLC4pfSAlPiUgI3JlbW92ZSBSVCAocmV0d2VldHMpCiAge2dzdWIoImh0dHBbXls6Ymxhbms6XV0rIiwiIiwuKX0gJT4lICNyZW1vdmUgbGlua3MgdGhhdCBzdGFydCB3aXRoIGh0dHAKICB7Z3N1YigiQFxcdSsiLCIiLC4pfSAlPiUgI3JlbW92ZSBuYW1lcyAKICB7Z3N1YignQFxcdysnLCAnJywgLil9ICU+JSAjIHJlbW92ZSBhdCBwZW9wbGUKICB7Z3N1YigiW1s6cHVuY3Q6XV0iLCIgIiwuKX0gJT4lI3JlbW92ZSBwdW5jdHVhdGlvbgogIHtnc3ViKCJbXls6YWxudW06XV0iLCIgIiwuKX0lPiUjcmVtb3ZlIHB1bmN0dWF0aW9uCiAgcmVtb3ZlTnVtYmVycygpICU+JQogIHJlbW92ZVdvcmRzKHN0b3B3b3JkcygiZW5nbGlzaCIpKSAlPiUKICBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoc3RvcHdvcmRzX3JlZ2V4LCAnJyklPiUgI3JlbW92ZSBzdG9wIHdvcmRzCiAgdW5pcXVlKCkgI3JlbW92ZSBkdXBsaWNhdGVzCmBgYAoKIyMjIFJlc3VsdHMKCmBgYHtyIFdvcmRjbG91ZCBTYW1zdW5nLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp3b3JkY2xvdWQod29yZF9zLCBtaW4uZnJlcSA9IDYwLCBtYXgud29yZHMgPSA0MCwgcmFuZG9tLm9yZGVyID0gRkFMU0UsIGNvbG9yPSBwYWwpCmBgYAoKU2Ftc3VuZyBTMjIgdXNlcnMgbWVudGlvbmVkIFNhbXN1bmcsIEdhbGF4eSAod2hpY2ggaXMgdGhlIHNlcmllcyBvZiB0aGUgUzIyKSBhbmQgVWx0cmEgKHdoaWNoIGlzIGEgc3BlY2lmaWMgbW9kZWwpLiBUaGUgVWx0cmEgbW9kZWwgaXMgY29tcGFyYWJsZSB0byB0aGUgaVBob25lIDEzIFByby4KCkFsc28gaVBob25lLCBQcm8sIE1heCwgTm90ZSAmIE9uZVBsdXMgYXJlIG1lbnRpb25lZCB3aGljaCBhcmUgb3RoZXIgY29tcGFyYWJsZSBzbWFydHBob25lcyBpbiB0aGUgbWFya2V0LgoKT3RoZXIgd29yZHMgdGhhdCBhcmUgb2Z0ZW4gbWVudGlvbmVkIGJlbG9uZyB0byBzcGVjaWZpY2F0aW9ucyB0aGF0IHVzZXJzIHRhbGtlZCBhYm91dDoKCi0gICBhbmRyb2lkLCB1cGRhdGUsIHNlY3VyaXR5CgotICAgY2FtZXJhLCBwaXhlbCwgdmlkZW8KCi0gICBmZWF0dXJlcwoKLSAgIG1lZGlhdGVrCgotICAgc2NyZWVuCgotICAgYW1wCgotICAgY2FzZQoKYGBge3IgV29yZGNsb3VkIEFwcGxlLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp3b3JkY2xvdWQod29yZF9hLCBtaW4uZnJlcSA9IDYwLCBtYXgud29yZHMgPSA0MCwgcmFuZG9tLm9yZGVyID0gRkFMU0UsIGNvbG9yPSBwYWwpCmBgYAoKV2UgY2FuIGlkZW50aWZ5IHRoYXQgQXBwbGUgaVBob25lIGlzIG1lbnRpb25lZCBpbiB0aGUgdmFyaWFudHMgUHJvLCBNaW5pIGFuZCBNYXguIFBybyBzZWVtcyB0byBiZSB0aGUgbW9zdCBpbXBvcnRhbnQgb25lLCB0aGVuIE1heCBhbmQgdGhlbiB0aGUgTWluaS4KCkFzIHdpdGggdGhlIFNhbXN1bmcgUzIyLCBhbHNvIGhlcmUgaXQgaXMgbWVudGlvbmVkIHdpdGggIlVsdHJhIiwgIkdhbGF4eSIgYW5kICJTYW1zdW5nIi4KClRoZSBzcGVjaWZpY2F0aW9ucyBvZiB0aGUgcGhvbmUgdGhhdCB1c2VycyB0YWxrZWQgYWJvdXQgd2VyZToKCi0gICBwaXhlbCwgY2FtZXJhCgotICAgYmF0dGVyeSwgYW1wCgotICAgcHJpY2UKCi0gICBjYXNlCgotICAgZ3JlZW4KCkZvciBpUGhvbmUgMTMsIHdlIGNhbiBub3RpY2UgdGhhdCBzb21lIGFkamVjdGl2ZXMgYW5kIHZlcmJzIHdlcmUgbWVudGlvbmVkIGEgbG90OgoKYXZhaWxhYmxlLCBidXksIHdpbiwgZnJlZSwgc3RpbGwsIG5vdywgZ29vZCwgYmV0dGVyLCBiZXN0LCBsaWtlLCB3aWxsLCBnZXQsIHdhbnQsIG5lZWQsIGNhbgoKV2Ugd2lsbCBpZGVudGlmeSB0b3BpY3MgZnVydGhlciBkdXJpbmcgb3VyIGFuYWx5c2lzIHVzaW5nIExEQSBUb3BpYyBNb2RlbGxpbmcuCgojIyMgSW5zaWdodHMKCkJvdGggbW9kZWxzIGFyZSBtZW50aW9uZWQgd2l0aCB0aGVpciBjYW1lcmEgYW5kIHBpeGVsIGJ1dCBvbmx5IFNhbXN1bmcgaGFzIHRoZSB3b3JkICJ2aWRlbyIgbWVudGlvbmVkIGEgbG90LiBXZSBpZGVudGlmaWVkIGluIG91ciBwcmUtcmVzZWFyY2ggYWJvdXQgdGhlIHBob25lcyB0aGF0IGJvdGggY29tcGFuaWVzIGFkdmVydGlzZSB0aGVpciBzbWFydHBob25lcyBiYXNlZCBvbiB0aGUgY2FtZXJhLiBOb25lIG9mIGJvdGggbWVudGlvbnMgYWJvdXQgcG9zaXRpdmUgYWJpbGl0aWVzIGluIHRoZSB2aWRlbyByZWNvcmRpbmcgaW4gdGhlaXIgbWFpbiBhZHZlcnRpc2VtZW50LgoKRm9yIFNhbXN1bmcgUzIyIHVzZXJzIGl0IHNlZW1zIHRvIGJlIGltcG9ydGFudCB0aGF0IGEgbmV3IHVwZGF0ZSBoYXMgYmVlbiByZWxlYXNlZC4gQSBuZXcgQW5kcm9pZCBPUyB1cGRhdGUgZm9yIHRoZSBzZXJpZXMgUzIyIGhhcyBiZWVuIHJlbGVhc2VkIGluIEFwcmlsIDIwMjIgYW5kIHVwZGF0ZWQgc2VjdXJpdHkgbWVhc3VyZW1lbnRzIGFuZCBicm91Z2h0IG5ldyBmZWF0dXJlcy4KCkZvciBBcHBsZSBpUGhvbmUgMTMgaXQgaGFzIGJlZW4gdGFsa2VkIGEgbG90IGFib3V0IGdyZWVuLiBUaGUgZ2VuZXJhdGlvbiAxMyBoYXMgYmVlbiB0aGUgZmlyc3QgRmxhZ3NoaXAgbW9kZWwgdG8gYmUgcHJvZHVjZWQgaW4gdGhpcyBjb2xvdXIsIHRoZXJlZm9yZSBpdCBtYWtlcyBzZW5zZSB0aGF0IHBlb3BsZSBkaXNjdXNzIGFib3V0IGl0LgoKIyMgU2VudGltZW50IEFuYWx5c2lzCgojIyMgUHJlcHJvY2Vzc2luZyBUd2VldHMKCldlIG5lZWQgdG8gcHJlcHJvY2VzcyBkYXRhIHRoaXMgdGltZSBhZGRpdGlvbmFsbHkgd2l0aCB0aGUgZm9sbG93aW5nIHN0ZXBzOgoKLSAgIEVtb2ppcyB3ZXJlIHJlcGxhY2VkIGJ5IHRoZSB3b3JkIGZvcm0sIGUuZy4gU21pbGluZyBlbW9qaSB0byBzbWlsaW5nCgotICAgRW1vamkgSWRlbnRpZmllciB3ZXJlIHJlcGxhY2VkIGJ5IHRoZSB3b3JkIGZvcm0sIGUuZy4gOi0pIHRvIHNtaWxpbmcKCmBgYHtyIFNhbXN1bmcgUzIyIGRhdGEsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kc3RvcHdvcmRzX3JlZ2V4IDwtIHBhc3RlKHN0b3B3b3JkcygnZW4nKSwgY29sbGFwc2UgPSAnXFxifFxcYicpCnN0b3B3b3Jkc19yZWdleCA8LSBwYXN0ZTAoJ1xcYicsIHN0b3B3b3Jkc19yZWdleCwgJ1xcYicpCgpTYW1zdW5nX2RmIDwtIHNhbXN1bmdfZGYkdGV4dCAlPiUKICBzdHJfdG9fbG93ZXIoKSAlPiUgI2FsbCB0ZXh0IHRvIGxvd2VyIGNhc2UKICByZXBsYWNlX2NvbnRyYWN0aW9uKCkgJT4lICNyZXBsYWNlcyBjb250cmFjdGlvbnMgdG8gbG9uZ2VyIGZvcm0KICByZXBsYWNlX2ludGVybmV0X3NsYW5nKCkgJT4lICNyZXBsYWNlcyBjb21tb24gaW50ZXJuZXQgc2xhbmcKICByZXBsYWNlX2hhc2gocmVwbGFjZW1lbnQgPSAiIikgJT4lICNyZW1vdmVzIGhhc2h0YWdzCiAgcmVwbGFjZV93b3JkX2Vsb25nYXRpb24oKSAlPiUgI3JlbW92ZXMgd29yZCBlbG9uZ2F0aW9uLCBlLmcuICJoZWVlZWV5IiB0byAiaGV5IgogIHJlcGxhY2VfZW1vamkoKSAlPiUgI3JlcGxhY2VzIGVtb2ppcyB3aXRoIHRoZSB3b3JkIGZvcm0gCiAgcmVwbGFjZV9lbW9qaV9pZGVudGlmaWVyKCkgJT4lICNyZXBsYWNlcyBlbW9qaSBpZGVudGlmaWVycyB0byB3b3JkIGZvcm0gCiAgcmVwbGFjZV9ub25fYXNjaWkoKSAlPiUgI3JlcGxhY2VzIGNvbW1vbiBub24tQVNDSUkgY2hhcmFjdGVycy4gCiAgc3RyX3NxdWlzaCgpICU+JSAjcmVkdWNlcyByZXBlYXRlZCB3aGl0ZXNwYWNlIGluc2lkZSBhIHN0cmluZwogIHN0cl90cmltKCkgJT4lICNyZW1vdmVzIHdoaXRlc3BhY2UgZnJvbSBzdGFydCBhbmQgZW5kIG9mIHN0cmluZwogIHtnc3ViKCIoUlR8dmlhKSgoPzpcXGJcXFcqQFxcdyspKykiLCIiLC4pfSAlPiUgI3JlbW92ZSBSVCAocmV0d2VldHMpCiAge2dzdWIoImh0dHBbXls6Ymxhbms6XV0rIiwiIiwuKX0gJT4lICNyZW1vdmUgbGlua3MgdGhhdCBzdGFydCB3aXRoIGh0dHAKICB7Z3N1YigiQFxcdSsiLCIiLC4pfSAlPiUgI3JlbW92ZSBuYW1lcyAKICB7Z3N1YignQFxcdysnLCAnJywgLil9ICU+JSAjIHJlbW92ZSBhdCBwZW9wbGUKICB7Z3N1YigiW1s6cHVuY3Q6XV0iLCIgIiwuKX0gJT4lI3JlbW92ZSBwdW5jdHVhdGlvbgogIHtnc3ViKCJbXls6YWxudW06XV0iLCIgIiwuKX0lPiUjcmVtb3ZlIHB1bmN0dWF0aW9uCiAge2dzdWIoInBybyIsIiAiLC4pfSU+JSNyZW1vdmVzIHRoZSB3b3JkICJwcm8iIGJlY2F1c2UgaXRzIGEgZGlmZmVyZW50IGNvbnRleHQgaGVyZWluCiAgc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKHN0b3B3b3Jkc19yZWdleCwgJycpICU+JSAjcmVtb3ZlIHN0b3Agd29yZHMKICB1bmlxdWUoKSNyZW1vdmUgZHVwbGljYXRlcwoKdGFpbChTYW1zdW5nX2RmKQpgYGAKCmBgYHtyIEFwcGxlIGlQaG9uZSAxMyBkYXRhLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CkFwcGxlX2RmIDwtIGFwcGxlX2RmJHRleHQgJT4lCiAgc3RyX3RvX2xvd2VyKCkgJT4lICNhbGwgdGV4dCB0byBsb3dlciBjYXNlCiAgcmVwbGFjZV9jb250cmFjdGlvbigpICU+JSAjcmVwbGFjZXMgY29udHJhY3Rpb25zIHRvIGxvbmdlciBmb3JtCiAgcmVwbGFjZV9pbnRlcm5ldF9zbGFuZygpICU+JSAjcmVwbGFjZXMgY29tbW9uIGludGVybmV0IHNsYW5nCiAgcmVwbGFjZV9oYXNoKHJlcGxhY2VtZW50ID0gIiIpICU+JSAjcmVtb3ZlcyBoYXNodGFncwogIHJlcGxhY2Vfd29yZF9lbG9uZ2F0aW9uKCkgJT4lICNyZW1vdmVzIHdvcmQgZWxvbmdhdGlvbiwgZS5nLiAiaGVlZWVleSIgdG8gImhleSIKICByZXBsYWNlX2Vtb2ppKCkgJT4lICNyZXBsYWNlcyBlbW9qaXMgd2l0aCB0aGUgd29yZCBmb3JtIAogIHJlcGxhY2VfZW1vamlfaWRlbnRpZmllcigpICU+JSAjcmVwbGFjZXMgZW1vamkgaWRlbnRpZmllcnMgdG8gd29yZCBmb3JtIAogIHJlcGxhY2Vfbm9uX2FzY2lpKCkgJT4lICNyZXBsYWNlcyBjb21tb24gbm9uLUFTQ0lJIGNoYXJhY3RlcnMuIAogIHN0cl9zcXVpc2goKSAlPiUgI3JlZHVjZXMgcmVwZWF0ZWQgd2hpdGVzcGFjZSBpbnNpZGUgYSBzdHJpbmcKICBzdHJfdHJpbSgpICU+JSAjcmVtb3ZlcyB3aGl0ZXNwYWNlIGZyb20gc3RhcnQgYW5kIGVuZCBvZiBzdHJpbmcKICB7Z3N1YigiKFJUfHZpYSkoKD86XFxiXFxXKkBcXHcrKSspIiwiIiwuKX0gJT4lICNyZW1vdmUgUlQgKHJldHdlZXRzKQogIHtnc3ViKCJodHRwW15bOmJsYW5rOl1dKyIsIiIsLil9ICU+JSAjcmVtb3ZlIGxpbmtzIHRoYXQgc3RhcnQgd2l0aCBodHRwCiAge2dzdWIoIkBcXHUrIiwiIiwuKX0gJT4lICNyZW1vdmUgbmFtZXMgCiAge2dzdWIoJ0BcXHcrJywgJycsIC4pfSAlPiUgIyByZW1vdmUgYXQgcGVvcGxlCiAge2dzdWIoIltbOnB1bmN0Ol1dIiwiICIsLil9ICU+JSNyZW1vdmUgcHVuY3R1YXRpb24KICB7Z3N1YigiW15bOmFsbnVtOl1dIiwiICIsLil9JT4lI3JlbW92ZSBwdW5jdHVhdGlvbgogIHtnc3ViKCJwcm8iLCIgIiwuKX0lPiUjcmVtb3ZlcyB0aGUgd29yZCAicHJvIiBiZWNhdXNlIGl0cyBhIGRpZmZlcmVudCBjb250ZXh0IGhlcmVpbgogIHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbChzdG9wd29yZHNfcmVnZXgsICcnKSAlPiUgI3JlbW92ZSBzdG9wIHdvcmRzCiAgdW5pcXVlKCkgI3JlbW92ZSBkdXBsaWNhdGVzCiAgCiAgCnRhaWwoQXBwbGVfZGYpCmBgYAoKIyMjIFNlbnRpbWVudHMgaW4gVHdlZXRzCgpUaGUgc2VudGltZW50IGFuYWx5c2lzCgpgYGB7ciBTYW1zdW5nIFNlbnRpbWVudCBTY29yZXMsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyMjIHNlbnRpbWVudCBhbmFseXNpcyAjIyMjIwpteXNlbnRpbWVudDwtIGdldF9ucmNfc2VudGltZW50KFNhbXN1bmdfZGYpCnNlbnRpbWVudHNjb3JlczwtIGRhdGEuZnJhbWUoY29sU3VtcyhteXNlbnRpbWVudFssXSkpCgojIyMjIyMgZ2V0dGluZyBzZW50aW1lbnQgc2NvcmVzICMjIyMjIwpuYW1lcyhzZW50aW1lbnRzY29yZXMpPC0ic2NvcmUiCnNlbnRpbWVudHNjb3JlczwtY2JpbmQoInNlbnRpbWVudCI9cm93bmFtZXMoc2VudGltZW50c2NvcmVzKSxzZW50aW1lbnRzY29yZXMpCnJvd25hbWVzKHNlbnRpbWVudHNjb3Jlcyk8LU5VTEwKCiMjIyMjIyBwbG90dGluZyBzZW50aW1lbnQgc2NvcmVzICMjIyMjIwpnZ3Bsb3QoZGF0YT1zZW50aW1lbnRzY29yZXMsYWVzKHg9c2VudGltZW50LHk9c2NvcmUpKSsKICBnZW9tX2JhcihhZXMoZmlsbD1zZW50aW1lbnQpLHN0YXQ9ImlkZW50aXR5IikrIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgeGxhYigic2VudGltZW50IikgK3lsYWIoInNjb3JlIikrIGdndGl0bGUoIlRvdGFsIFNlbnRpbWVudCBTY29yZSBiYXNlZCBvbiBUd2VldHMgYWJvdXQgU2Ftc3VuZyIpCmBgYAoKYGBge3IgQXBwbGUgU2VudGltZW50IFNjb3JlLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMjIyBzZW50aW1lbnQgYW5hbHlzaXMgIyMjIyMKbXlzZW50aW1lbnRfYXBwbGU8LSBnZXRfbnJjX3NlbnRpbWVudChBcHBsZV9kZikgCnNlbnRpbWVudHNjb3Jlc19hcHBsZTwtIGRhdGEuZnJhbWUoY29sU3VtcyhteXNlbnRpbWVudF9hcHBsZVssXSkpCgojIyMjIyMgZ2V0dGluZyBzZW50aW1lbnQgc2NvcmVzICMjIyMjIwpuYW1lcyhzZW50aW1lbnRzY29yZXNfYXBwbGUpPC0ic2NvcmUiCnNlbnRpbWVudHNjb3Jlc19hcHBsZTwtY2JpbmQoInNlbnRpbWVudCI9cm93bmFtZXMoc2VudGltZW50c2NvcmVzX2FwcGxlKSxzZW50aW1lbnRzY29yZXNfYXBwbGUpCnJvd25hbWVzKHNlbnRpbWVudHNjb3Jlc19hcHBsZSk8LU5VTEwKCiMjIyMjIyBwbG90dGluZyBzZW50aW1lbnQgc2NvcmVzICMjIyMjIwpnZ3Bsb3QoZGF0YT1zZW50aW1lbnRzY29yZXNfYXBwbGUsYWVzKHg9c2VudGltZW50LHk9c2NvcmUpKSsKICBnZW9tX2JhcihhZXMoZmlsbD1zZW50aW1lbnQpLHN0YXQ9ImlkZW50aXR5IikrIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgeGxhYigic2VudGltZW50IikgK3lsYWIoInNjb3JlIikrIGdndGl0bGUoIlRvdGFsIFNlbnRpbWVudCBTY29yZSBiYXNlZCBvbiBUd2VldHMgYWJvdXQgQXBwbGUiKQpgYGAKCmBgYHtyIENvbXBhcmlzb24sIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnJlbGF0aXZlX2NvbXBfc2VudGltZW50IDwtIGRhdGEuZnJhbWUoU2VudGltZW50ID0gc2VudGltZW50c2NvcmVzX2FwcGxlJHNlbnRpbWVudCwgQXBwbGVfaVBob25lXzEzID0gc2VudGltZW50c2NvcmVzX2FwcGxlJHNjb3JlL3N1bShzZW50aW1lbnRzY29yZXNfYXBwbGUkc2NvcmUpKjEwMCwgU2Ftc3VuZ19TMjIgPSBzZW50aW1lbnRzY29yZXMkc2NvcmUvc3VtKHNlbnRpbWVudHNjb3JlcyRzY29yZSkqMTAwKSAlPiUKICBtZWx0KGlkLnZhcnMgPSAxLCB2YXJpYWJsZS5uYW1lID0gInZhcmlhYmxlIiwKICAgICAgICAgICB2YWx1ZS5uYW1lPSJzY29yZSIpCgpnZ3Bsb3QocmVsYXRpdmVfY29tcF9zZW50aW1lbnQsIGFlcyh4PSBTZW50aW1lbnQsIHk9IHNjb3JlLCBmaWxsPXZhcmlhYmxlKSkgKwogIGdlb21fYmFyKHBvc2l0aW9uPSJkb2RnZSIsICBzdGF0PSJpZGVudGl0eSIpICsKICB4bGFiKCJzZW50aW1lbnQiKSAreWxhYigicGVyY2VudGFnZSIpKyBnZ3RpdGxlKCJSZWxhdGl2ZSBTZW50aW1lbnQgU2NvcmUgYmFzZWQgb24gVHdlZXRzIGFib3V0IEFwcGxlIGFuZCBTYW1zdW5nIikKYGBgCgpPbiB0aGUgZmlyc3QgbG9vaywgc2VudGltZW50cyBhcmUgc2ltaWxhciBmb3IgYm90aCBzbWFydHBob25lIG1vZGVscyBhbmQgYXJlIGNvbW1lbnRlZCBvbiB3aXRoIGhpZ2hseSBwb3NpdGl2ZSBzZW50aW1lbnRzLiBUaGlzIG1lYW5zIHRoYXQgb24gYm90aCBtb2RlbHMsIHVzZXJzIGFyZSBnZW5lcmFsbHkgc3BlYWtpbmcgcG9zaXRpdmVseSBhYm91dCB0aGVpciBzbWFydHBob25lLgoKU2Ftc3VuZyBTMjIgaGFzIG1vcmUgdHJ1c3QgYW5kIGFudGljaXBhdGlvbiB3aGlsZSBpUGhvbmUgMTMgYnJpbmdzIG1vcmUgam95IHRvIGl0cyB1c2VycyBidXQgYWxzbyBtb3JlIHNhZG5lc3MsIHN1cnByaXNlLCBmZWFyIGFuZCBkaXNndXN0LgoKYGBge3IgQXBwbGUgU2VudGltZW50IFN0YXRpc3RpY3MsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyMjIyBTZW50aW1lbnRyIHNjb3JlICMjIyMjIyMKc2VudGltZW50cl9hcHBsZSA8LSBzZW50aW1lbnRfYnkoQXBwbGVfZGYsIGJ5PU5VTEwpCiMgWW91IGNhbiBzZWUgdGhlIHNlbnRpbWVudCBwZXIgdHdlZXQgSUQ6CmdncGxvdChkYXRhPXNlbnRpbWVudHJfYXBwbGUsYWVzKHg9ZWxlbWVudF9pZCx5PWF2ZV9zZW50aW1lbnQsIGNvbG9yPWF2ZV9zZW50aW1lbnQpKSsKICBnZW9tX2xpbmUoKQojIFlvdSBjYW4gc2VlIHRoZSBzdW1tYXJ5IG9mIG1pbmltdW0sIElRUiwgbWVkaWFuIGFuZCBtZWFuIGZvciBhbGwgdmFyaWFibGVzLiBGb3IgdXMsIHdvcmRfY291bnQgYW5kIGF2ZV9zZW50aW1lbnQgYXJlIG1vc3RseSBpbnRlcmVzdGluZzoKc3VtbWFyeShzZW50aW1lbnRyX2FwcGxlKQoKIyBZb3UgY2FuIHNlZSB0aGUgdmFyaWFuY2UgYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBmb3IgdGhlIFNlbnRpbWVudCBTY29yZSAmIFdvcmQgQ291bnQ6CmRhdGEuZnJhbWUoIiAiPSBjKCJBdmVyYWdlIiwgIlZhcmlhbmNlIiwgIlN0YW5kYXJkIERldmlhdGlvbiIpLAoiU2VudGltZW50IFNjb3JlIiA9IGMocm91bmQobWVhbihzZW50aW1lbnRyX2FwcGxlJGF2ZV9zZW50aW1lbnQpLDIpLCByb3VuZCh2YXIoc2VudGltZW50cl9hcHBsZSRhdmVfc2VudGltZW50KSwyKSwKcm91bmQoc2Qoc2VudGltZW50cl9hcHBsZSRhdmVfc2VudGltZW50KSwyKSksIAoiV29yZCBDb3VudCI9Yyhyb3VuZChtZWFuKHNlbnRpbWVudHJfYXBwbGUkd29yZF9jb3VudCksMiksIHJvdW5kKHZhcihzZW50aW1lbnRyX2FwcGxlJHdvcmRfY291bnQpLDIpLApyb3VuZChzZChzZW50aW1lbnRyX2FwcGxlJHdvcmRfY291bnQpLDIpKSkKYGBgCgpgYGB7ciBTYW1zdW5nIFNlbnRpbWVudCBTdGF0aXN0aWNzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMjIyBTZW50aW1lbnRyIHNjb3JlICMjIyMjIwpzZW50aW1lbnRyX3NhbXN1bmcgPC0gc2VudGltZW50X2J5KFNhbXN1bmdfZGYsIGJ5PU5VTEwpCiMgWW91IGNhbiBzZWUgdGhlIHNlbnRpbWVudCBwZXIgdHdlZXQgSUQ6CmdncGxvdChkYXRhPXNlbnRpbWVudHJfc2Ftc3VuZyxhZXMoeD1lbGVtZW50X2lkLHk9YXZlX3NlbnRpbWVudCwgY29sb3I9YXZlX3NlbnRpbWVudCkpKwogIGdlb21fbGluZSgpCgojIFlvdSBjYW4gc2VlIHRoZSBzdW1tYXJ5IG9mIG1pbmltdW0sIElRUiwgbWVkaWFuIGFuZCBtZWFuIGZvciBhbGwgdmFyaWFibGVzLiBGb3IgdXMsIHdvcmRfY291bnQgYW5kIGF2ZV9zZW50aW1lbnQgYXJlIG1vc3RseSBpbnRlcmVzdGluZzoKc3VtbWFyeShzZW50aW1lbnRyX3NhbXN1bmcpCgojIFlvdSBjYW4gc2VlIHRoZSB2YXJpYW5jZSBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIGZvciB0aGUgU2VudGltZW50IFNjb3JlICYgV29yZCBDb3VudDoKZGF0YS5mcmFtZSgiICI9IGMoIkF2ZXJhZ2UiLCAiVmFyaWFuY2UiLCAiU3RhbmRhcmQgRGV2aWF0aW9uIiksCiJTZW50aW1lbnQgU2NvcmUiID0gYyhyb3VuZChtZWFuKHNlbnRpbWVudHJfc2Ftc3VuZyRhdmVfc2VudGltZW50KSwyKSwgcm91bmQodmFyKHNlbnRpbWVudHJfc2Ftc3VuZyRhdmVfc2VudGltZW50KSwyKSwKcm91bmQoc2Qoc2VudGltZW50cl9zYW1zdW5nJGF2ZV9zZW50aW1lbnQpLDIpKSwgCiJXb3JkIENvdW50Ij1jKHJvdW5kKG1lYW4oc2VudGltZW50cl9zYW1zdW5nJHdvcmRfY291bnQpLDIpLCByb3VuZCh2YXIoc2VudGltZW50cl9zYW1zdW5nJHdvcmRfY291bnQpLDIpLApyb3VuZChzZChzZW50aW1lbnRyX3NhbXN1bmckd29yZF9jb3VudCksMikpKQpgYGAKClNhbXN1bmcgUzIyIHR3ZWV0cyB3ZXJlIG9uIGF2ZXJhZ2UgMTAuNCB3b3JkcyBsb25nIHdoaWxlIEFwcGxlIGlQaG9uZSAxMyB0d2VldHMgaGFkIDkuOSB3b3Jkcy4gVGhlIHR3ZWV0IHdpdGggdGhlIG1heGltdW0gbnVtYmVyIG9mIHdvcmRzIHdhcyBhYm91dCBpUGhvbmUgMTMgd2l0aCAxMzUgaWRlbnRpZmllZCB3b3Jkcy4gU2Ftc3VuZyBTMjIgd2l0aCAzNCB3b3JkcyBtYXhpbXVtIHdvcmRzIGlzIHF1aXRlIHNob3J0ZXIuCgpUaGUgc2VudGltZW50ciBwYWNrYWdlIGluIFIgZXN0aW1hdGVzIHRoZSBzZW50aW1lbnQgcG9sYXJpdHkgYnkgc2VudGVuY2UuIFRoZSBhdmVyYWdlIHNlbnRpbWVudCBmb3IgaVBob25lIDEzIHdhcyBoaWdoZXIgZGlzdHJpYnV0ZWQgd2l0aCBhIHJhbmdlIGZyb20gLTEuNiB0byArMS45IHdpdGggaXRzIGF2ZXJhZ2UgYXQgMC4yNiB3aGlsZSBTYW1zdW5nIGhhZCBhIHNlbnRpbWVudCBwb2xhcml0eSBmcm9tIC0xLjEgdG8gKzEuNiB3aXRoIGl0cyBhdmVyYWdlIGF0IDAuMTUuIFRoZSBoaWdoZXIgdmFyaWFuY2Ugd2l0aGluIHRoZSBkYXRhIGlzIGlkZW50aWNhbCB0byBvdXIgZmluZGluZ3MgZnJvbSB0aGUgcGxvdCAiUmVsYXRpdmUgU2VudGltZW50IFNjb3JlIGJhc2VkIG9uIFR3ZWV0cyBhYm91dCBBcHBsZSBhbmQgU2Ftc3VuZyIgZWFybGllci4gV2UgY2FuIHNlZSBmcm9tIHRoaXMgdGhhdCBpUGhvbmUgMTMgdXNlcnMgYXJlIGluIGdlbmVyYWwgbW9yZSBlbW90aW9uYWwgLSBpbiBhIG5lZ2F0aXZlIGFuZCBwb3NpdGl2ZSBkaXJlY3Rpb24gLSB0aGFuIFNhbXN1bmcgUzIyIHVzZXJzLiBXZSBhc3N1bWUgdGhhdCBwZW9wbGUgYXJlIGVtb3Rpb25hbGx5IG1vcmUgZGVwZW5kZW50IG9uIHRoZWlyIGlQaG9uZSAxMyB0aGFuIFNhbXN1bmcgUzIyLgoKVG8gc2VlIHRoZSBzZW50aW1lbnRzIHBlciB0d2VldCwgZ2VuZXJhdGUgdGhpcyBIVE1MIGZpbGVzOgoKYGBge3IgSFRNTCBSZXBvcnRzLCBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQojIEhUTUwgd2l0aCBhbGwgdHdlZXRzIGhpZ2hsaWdodGVkIGJ5IGl0cyBzZW50aW1lbnQgcG9sYXJpdHkgc2NvcmU6CiMgCiMgIyBBcHBsZSBpUGhvbmUgMTMKIyBzZW50aW1lbnRyX2h0bWxfYSA8LSBzZW50aW1lbnRyX2FwcGxlICU+JQojICAgc2VudGltZW50X2J5KGJ5PU5VTEwpJT4lCiMgICBoaWdobGlnaHQoKQojIAojICMgU2Ftc3VuZyBTMjIKIyBzZW50aW1lbnRyX2h0bWxfcyA8LSBzZW50aW1lbnRyX3NhbXN1bmcgJT4lCiMgICBzZW50aW1lbnRfYnkoYnk9TlVMTCklPiUKIyAgIGhpZ2hsaWdodCgpCgpgYGAKCiMjIyBTZW50aW1lbnQgVGVybXMKCk5vdyB3ZSB3YW50IHRvIGV4dHJhY3QgdGhlIHNlbnRpbWVudCB0ZXJtcyBmb3IgYm90aCBwaG9uZXMuIFdoYXQgaXMgbGlrZWQgYnkgdGhlIHVzZXJzPyBXaGF0IGlzIG5vdD8KCiMjIyMgU2Ftc3VuZyBTMjIKCmBgYHtyIFNhbXN1bmcgLSBQb3NpdGl2ZSBTZW50aW1lbnRzLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzZW50aW1lbnR0ZXJtc19zIDwtIGF0dHJpYnV0ZXMoZXh0cmFjdF9zZW50aW1lbnRfdGVybXMoU2Ftc3VuZ19kZikpJGNvdW50ICU+JQogIG11dGF0ZSh3ZWlnaHRfaW5fcGVyYyA9IHJvdW5kKHBvbGFyaXR5Km4vc3VtKHBvbGFyaXR5Km4pKjEwMCxkaWdpdHM9MikpICU+JQogIGFycmFuZ2UoZGVzYyh3ZWlnaHRfaW5fcGVyYykpICU+JQogIGZpbHRlcihhYnMocG9sYXJpdHkpPjAuMDEpCgpoZWFkKHNlbnRpbWVudHRlcm1zX3MsMTApCmBgYAoKYGBge3IgU2Ftc3VuZyBQb3NpdGl2ZSBXb3JkcywgZWNobz1GQUxTRX0KI25ncmFtID0gMQpiZ19kZl9zIDwtIGRhdGEuZnJhbWUod29yZF9zKQoKc19iaWdyYW0gPC0gYmdfZGZfcyAlPiUKICB1bm5lc3RfdG9rZW5zKG91dHB1dD1iaWdyYW1zLCBpbnB1dD13b3JkX3MsIHRva2VuPSJ3b3JkcyIsIGZvcm1hdD0gInRleHQiKQoKc19iaWdyYW1fY291bnRlZCA8LSBzX2JpZ3JhbSAlPiUgY291bnQoKQpzX2JpZ3JhbV9jb3VudGVkJHNlbnRpbWVudCA8LSBnZXRfc2VudGltZW50KHNfYmlncmFtX2NvdW50ZWQkYmlncmFtcykKCmdncGxvdChzX2JpZ3JhbV9jb3VudGVkLCBhZXMoeD1iaWdyYW1zLCB5PWZyZXEpKSsKICBnZW9tX2NvbCgpCnNfYmlncmFtX3dpdGhfc2VudGltZW50IDwtIHNfYmlncmFtX2NvdW50ZWQgJT4lCiAgbXV0YXRlKHdlaWdodGFnZSA9IHNlbnRpbWVudCpmcmVxKSAlPiUKICBhcnJhbmdlKGRlc2Mod2VpZ2h0YWdlKSkgJT4lCiAgdG9wX24oMjUpCgpnZ3Bsb3Qoc19iaWdyYW1fd2l0aF9zZW50aW1lbnQsIGFlcyh4PWJpZ3JhbXMsIHk9d2VpZ2h0YWdlKSkrCiAgZ2VvbV9jb2woKSsKICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDUpKSsKICB4bGFiKCJQb3NpdGl2ZSBXb3JkIikgKwogIGdndGl0bGUoIlJlbGF0aXZlIEltcG9ydGFuY2Ugb2YgUG9zaXRpdmUgV29yZHMiKQpgYGAKCmBgYHtyIFNhbXN1bmcgLSBOZWdhdGl2ZSBTZW50aW1lbnRzLCBlY2hvPUZBTFNFfQp0YWlsKHNlbnRpbWVudHRlcm1zX3MsMTApCmBgYAoKYGBge3IgU2Ftc3VuZywgZWNobz1GQUxTRX0KIyMjIyMgQ3JlYXRpbmcgYSBwbG90IG9mIHRoZSBuZWdhdGl2ZSB3b3JkcyBtb3N0IGZyZXF1ZW50bHkgdXNlZCAjIyMjIwoKc19iaWdyYW1fd2l0aF9uZWdfc2VudGltZW50IDwtIHNfYmlncmFtX2NvdW50ZWQgJT4lCiAgbXV0YXRlKHdlaWdodGFnZSA9IHNlbnRpbWVudCpmcmVxKSAlPiUKICBhcnJhbmdlKGRlc2Mod2VpZ2h0YWdlKSkgJT4lCiAgdGFpbCgyNSkKCmdncGxvdChzX2JpZ3JhbV93aXRoX25lZ19zZW50aW1lbnQsIGFlcyh4PWJpZ3JhbXMsIHk9LXdlaWdodGFnZSkpKwogIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNSkpKwogIGdlb21fY29sKCkrCiAgICB4bGFiKCJOZWdhdGl2ZSBXb3JkIikgKwogIGdndGl0bGUoIlJlbGF0aXZlIEltcG9ydGFuY2Ugb2YgTmVnYXRpdmUgV29yZHMiKQoKYGBgCgpTY2FuZGFsIGlzIHJlbGF0ZWQgdG8gdGhlIEdPUyBhcHAgdGhhdCBzbG93ZWQgU2Ftc3VuZyBwaG9uZXMgZG93biBvbiBwdXJwb3NlIHRvIHNhdmUgYmF0dGVyeSBsaWZlIHdpdGhvdXQgbm90aWZ5aW5nIHRoZSB1c2VyIGFib3V0IGl0LgoKIyMjIyBBcHBsZSBpUGhvbmUgMTMKCmBgYHtyIEFwcGxlIC0gUG9zaXRpdmUgU2VudGltZW50LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzZW50aW1lbnR0ZXJtc19hIDwtIGF0dHJpYnV0ZXMoZXh0cmFjdF9zZW50aW1lbnRfdGVybXMoQXBwbGVfZGYpKSRjb3VudCAlPiUKICBtdXRhdGUod2VpZ2h0X2luX3BlcmMgPSByb3VuZChwb2xhcml0eSpuL3N1bShwb2xhcml0eSpuKSoxMDAsZGlnaXRzPTIpKSAlPiUKICBhcnJhbmdlKGRlc2Mod2VpZ2h0X2luX3BlcmMpKSAlPiUKICBmaWx0ZXIoYWJzKHBvbGFyaXR5KT4wLjAxKQoKaGVhZChzZW50aW1lbnR0ZXJtc19hLCAxMCkKYGBgCgpgYGB7ciBBcHBsZSBQb3NpdGl2ZSBXb3JkcywgZWNobz1GQUxTRX0KIyMjIyMgQ3JlYXRpbmcgYSBwbG90IG9mIHRoZSBwb3NpdGl2ZSB3b3JkcyBtb3N0IGZyZXF1ZW50bHkgdXNlZCAjIyMjIwoKYmdfZGZfYSA8LSBkYXRhLmZyYW1lKHdvcmRfYSkKCmFfYmlncmFtIDwtIGJnX2RmX2EgJT4lCiAgdW5uZXN0X3Rva2VucyhvdXRwdXQ9YmlncmFtcywgaW5wdXQ9d29yZF9hLCB0b2tlbj0id29yZHMiLCBmb3JtYXQ9ICJ0ZXh0IikKCmFfYmlncmFtX2NvdW50ZWQgPC0gYV9iaWdyYW0gJT4lIGNvdW50KCkKYV9iaWdyYW1fY291bnRlZCRzZW50aW1lbnQgPC0gZ2V0X3NlbnRpbWVudChhX2JpZ3JhbV9jb3VudGVkJGJpZ3JhbXMpCgojIGdncGxvdChhX2JpZ3JhbV9jb3VudGVkLCBhZXMoeD1iaWdyYW1zLCB5PWZyZXEpKSsKIyAgIGdlb21fY29sKCkKYV9iaWdyYW1fd2l0aF9zZW50aW1lbnQgPC0gYV9iaWdyYW1fY291bnRlZCAlPiUKICBtdXRhdGUod2VpZ2h0YWdlID0gc2VudGltZW50KmZyZXEpICU+JQogIGFycmFuZ2UoZGVzYyh3ZWlnaHRhZ2UpKSAlPiUKICB0b3BfbigyNSkKCmdncGxvdChhX2JpZ3JhbV93aXRoX3NlbnRpbWVudCwgYWVzKHg9YmlncmFtcywgeT13ZWlnaHRhZ2UpKSsKICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDUpKSsKICBnZW9tX2NvbCgpICArCiAgeGxhYigiUG9zaXRpdmUgV29yZCIpICsKICBnZ3RpdGxlKCJSZWxhdGl2ZSBJbXBvcnRhbmNlIG9mIFBvc2l0aXZlIFdvcmRzIikKYGBgCgpgYGB7ciBBcHBsZSAtIE5lZ2F0aXZlIFNlbnRpbWVudCwgZWNobz1GQUxTRX0KdGFpbChzZW50aW1lbnR0ZXJtc19hLDEwKQpgYGAKCmBgYHtyIEFwcGxlLCBlY2hvPUZBTFNFfQojIyMjIyBDcmVhdGluZyBhIHBsb3Qgb2YgdGhlIG5lZ2F0aXZlIHdvcmRzIG1vc3QgZnJlcXVlbnRseSB1c2VkICMjIyMjCgphX2JpZ3JhbV93aXRoX25lZ19zZW50aW1lbnQgPC0gYV9iaWdyYW1fY291bnRlZCAlPiUKICBtdXRhdGUod2VpZ2h0YWdlID0gc2VudGltZW50KmZyZXEpICU+JQogIGFycmFuZ2UoZGVzYyh3ZWlnaHRhZ2UpKSAlPiUKICB0YWlsKDI1KQoKZ2dwbG90KGFfYmlncmFtX3dpdGhfbmVnX3NlbnRpbWVudCwgYWVzKHg9YmlncmFtcywgeT0td2VpZ2h0YWdlKSkrCiAgICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDUpKSsKICAgIGdlb21fY29sKCkrCiAgICB4bGFiKCJOZWdhdGl2ZSBXb3JkIikgKwogICAgZ2d0aXRsZSgiUmVsYXRpdmUgSW1wb3J0YW5jZSBvZiBOZWdhdGl2ZSBXb3JkcyIpCmBgYAoKIyMgV29yZCBDb3JyZWxhdGlvbgoKIyMjIFNhbXN1bmcgUzIyCgpgYGB7ciBDb3JyZWxhdGlvblNhbXN1bmcxLCBlY2hvPUZBTFNFfQpzX3dvcmRzX3Blcl90d2VldCA8LSBkYXRhLmZyYW1lKGJnX2RmX3MpICU+JQogIGRwbHlyOjptdXRhdGUodHdlZXQgPSByb3dfbnVtYmVyKCkpICU+JQogIHVubmVzdF90b2tlbnMob3V0cHV0PWJpZ3JhbXMsIGlucHV0PXdvcmRfcywgZm9ybWF0PSAidGV4dCIsIHRva2VuID0gIm5ncmFtcyIsIG49MSkKCnNfd29yZF9wYWlycyA8LSBzX3dvcmRzX3Blcl90d2VldCAlPiUKICBwYWlyd2lzZV9jb3VudChiaWdyYW1zLCB0d2VldCwgc29ydCA9IFRSVUUpCgpzX3dvcmRfY29ycyA8LSBzX3dvcmRzX3Blcl90d2VldCAlPiUKICBncm91cF9ieShiaWdyYW1zKSAlPiUKICBmaWx0ZXIobigpID49IDIwKSAlPiUKICBwYWlyd2lzZV9jb3IoYmlncmFtcywgdHdlZXQsIHNvcnQgPSBUUlVFKQoKc193b3JkX2NvcnMKCnNfd29yZF9jb3JzICU+JQogIGZpbHRlcihpdGVtMSAlaW4lIGMoImFuZHJvaWQiLCAidXBkYXRlIiwgInNlY3VyaXR5IiwiY2FtZXJhIiwgInBpeGVsIiwgInZpZGVvIiwiZmVhdHVyZXMiLCAibWVkaWF0ZWsiLCJzY3JlZW4iLCJhbXAiLCJjYXNlIikpICU+JQogIGdyb3VwX2J5KGl0ZW0xKSAlPiUKICBzbGljZV9tYXgoY29ycmVsYXRpb24sIG4gPSA2KSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKGl0ZW0yID0gcmVvcmRlcihpdGVtMiwgY29ycmVsYXRpb24pKSAlPiUKICBnZ3Bsb3QoYWVzKGl0ZW0yLCBjb3JyZWxhdGlvbikpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIGZhY2V0X3dyYXAofiBpdGVtMSwgc2NhbGVzID0gImZyZWUiKSArCiAgY29vcmRfZmxpcCgpCgpzX3dvcmRfY29ycyAlPiUKICBmaWx0ZXIoaXRlbTEgJWluJSBjKCJhdmFpbGFibGUiLCAiYnV5Iiwid2luIiwgImZyZWUiLCJzdGlsbCIsIm5vdyIsICJnb29kIiwgImJldHRlciIsICJiZXN0IiwgImxpa2UiLCJ3aWxsIiwgImdldCIsICJ3YW50IiwgIm5lZWQiLCAiY2FuIikpICU+JQogIGdyb3VwX2J5KGl0ZW0xKSAlPiUKICBzbGljZV9tYXgoY29ycmVsYXRpb24sIG4gPSA2KSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKGl0ZW0yID0gcmVvcmRlcihpdGVtMiwgY29ycmVsYXRpb24pKSAlPiUKICBnZ3Bsb3QoYWVzKGl0ZW0yLCBjb3JyZWxhdGlvbikpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIGZhY2V0X3dyYXAofiBpdGVtMSwgc2NhbGVzID0gImZyZWUiKSArCiAgY29vcmRfZmxpcCgpCmBgYAoKYGBge3IgQ29ycmVsYXRpb25TYW1zdW5nLCBlY2hvPUZBTFNFfQpzX3dvcmRfY29ycyAlPiUKICBmaWx0ZXIoY29ycmVsYXRpb24gPiAuMjgpICU+JQogIGdyYXBoX2Zyb21fZGF0YV9mcmFtZSgpICU+JQogIGdncmFwaChsYXlvdXQgPSAiZnIiKSArCiAgZ2VvbV9lZGdlX2xpbmsoYWVzKGVkZ2VfYWxwaGEgPSBjb3JyZWxhdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBnZW9tX25vZGVfcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIiwgc2l6ZSA9IDUpICsKICBnZW9tX25vZGVfdGV4dChhZXMobGFiZWwgPSBuYW1lKSwgcmVwZWwgPSBUUlVFKSArCiAgdGhlbWVfdm9pZCgpCmBgYAoKIyMjIEFwcGxlIGlQaG9uZSAxMwoKYGBge3IgQ29ycmVsYXRpb25BcHBsZTEsIGVjaG89RkFMU0V9CmFfd29yZHNfcGVyX3R3ZWV0IDwtIGRhdGEuZnJhbWUoYmdfZGZfYSkgJT4lCiAgZHBseXI6Om11dGF0ZSh0d2VldCA9IHJvd19udW1iZXIoKSkgJT4lCiAgdW5uZXN0X3Rva2VucyhvdXRwdXQ9YmlncmFtcywgaW5wdXQ9d29yZF9hLCBmb3JtYXQ9ICJ0ZXh0IiwgdG9rZW4gPSAibmdyYW1zIiwgbj0xKQoKYV93b3JkX3BhaXJzIDwtIGFfd29yZHNfcGVyX3R3ZWV0ICU+JQogIHBhaXJ3aXNlX2NvdW50KGJpZ3JhbXMsIHR3ZWV0LCBzb3J0ID0gVFJVRSkKCmFfd29yZF9jb3JzIDwtIGFfd29yZHNfcGVyX3R3ZWV0ICU+JQogIGdyb3VwX2J5KGJpZ3JhbXMpICU+JQogIGZpbHRlcihuKCkgPj0gMjApICU+JQogIHBhaXJ3aXNlX2NvcihiaWdyYW1zLCB0d2VldCwgc29ydCA9IFRSVUUpCgphX3dvcmRfY29ycwoKYV93b3JkX2NvcnMgJT4lCiAgZmlsdGVyKGl0ZW0xICVpbiUgYygicGl4ZWwiLCAiY2FtZXJhIiwgImJhdHRlcnkiLCAiYW1wIiwgInByaWNlIiwgImNhc2UiLCAiZ3JlZW4iKSkgJT4lCiAgZ3JvdXBfYnkoaXRlbTEpICU+JQogIHNsaWNlX21heChjb3JyZWxhdGlvbiwgbiA9IDYpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUoaXRlbTIgPSByZW9yZGVyKGl0ZW0yLCBjb3JyZWxhdGlvbikpICU+JQogIGdncGxvdChhZXMoaXRlbTIsIGNvcnJlbGF0aW9uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgZmFjZXRfd3JhcCh+IGl0ZW0xLCBzY2FsZXMgPSAiZnJlZSIpICsKICBjb29yZF9mbGlwKCkKCmFfd29yZF9jb3JzICU+JQogIGZpbHRlcihpdGVtMSAlaW4lIGMoImF2YWlsYWJsZSIsICJidXkiLCJ3aW4iLCAiZnJlZSIsInN0aWxsIiwibm93IiwgImdvb2QiLCAiYmV0dGVyIiwgImJlc3QiLCAibGlrZSIsIndpbGwiLCAiZ2V0IiwgIndhbnQiLCAibmVlZCIsICJjYW4iKSkgJT4lCiAgZ3JvdXBfYnkoaXRlbTEpICU+JQogIHNsaWNlX21heChjb3JyZWxhdGlvbiwgbiA9IDYpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUoaXRlbTIgPSByZW9yZGVyKGl0ZW0yLCBjb3JyZWxhdGlvbikpICU+JQogIGdncGxvdChhZXMoaXRlbTIsIGNvcnJlbGF0aW9uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgZmFjZXRfd3JhcCh+IGl0ZW0xLCBzY2FsZXMgPSAiZnJlZSIpICsKICBjb29yZF9mbGlwKCkKCgpgYGAKCmBgYHtyIENvcnJlbGF0aW9uQXBwbGUsIGVjaG89RkFMU0V9CmFfd29yZF9jb3JzICU+JQogIGZpbHRlcihjb3JyZWxhdGlvbiA+IC4yOCkgJT4lCiAgZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKCkgJT4lCiAgZ2dyYXBoKGxheW91dCA9ICJmciIpICsKICBnZW9tX2VkZ2VfbGluayhhZXMoZWRnZV9hbHBoYSA9IGNvcnJlbGF0aW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGdlb21fbm9kZV9wb2ludChjb2xvciA9ICJsaWdodGJsdWUiLCBzaXplID0gNSkgKwogIGdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCByZXBlbCA9IFRSVUUpICsKICB0aGVtZV92b2lkKCkKYGBgCgojIyBDbHVzdGVyaW5nCgpgYGB7ciBDbHVzdGVyaW5nIFNhbXN1bmd9CnRkbV9zIDwtIGNvcnB1czwtIENvcnB1cyhWZWN0b3JTb3VyY2Uod29yZF9zKSkgCnRkbV9zIDwtIFRlcm1Eb2N1bWVudE1hdHJpeCh0ZG1fcykKdGRtX3MyIDwtIHJlbW92ZVNwYXJzZVRlcm1zKHRkbV9zLCBzcGFyc2UgPSAwLjk1KQptczIgPC0gYXMubWF0cml4KHRkbV9zMikKIyBjbHVzdGVyIHRlcm1zCmRpc3RNYXRyaXhfcyA8LSBkaXN0KHNjYWxlKG1zMikpCmZpdF9zIDwtIGhjbHVzdChkaXN0TWF0cml4X3MsIG1ldGhvZCA9ICJ3YXJkLkQiKQpwbG90KGZpdF9zKQpyZWN0LmhjbHVzdChmaXRfcywgayA9IDYsYm9yZGVyID0gInJlZCIpICMgY3V0IHRyZWUgaW50byA2IGNsdXN0ZXJzCmBgYAoKYGBge3IgQ2x1c3RlcmluZyBBcHBsZX0KdGRtX2EgPC0gY29ycHVzPC0gQ29ycHVzKFZlY3RvclNvdXJjZSh3b3JkX2EpKSAKdGRtX2EgPC0gVGVybURvY3VtZW50TWF0cml4KHRkbV9hKQp0ZG1fYTIgPC0gcmVtb3ZlU3BhcnNlVGVybXModGRtX2EsIHNwYXJzZSA9IDAuOTUpCm1hMiA8LSBhcy5tYXRyaXgodGRtX2EyKQojIGNsdXN0ZXIgdGVybXMKZGlzdE1hdHJpeF9hIDwtIGRpc3Qoc2NhbGUobWEyKSkKZml0X2EgPC0gaGNsdXN0KGRpc3RNYXRyaXhfYSwgbWV0aG9kID0gIndhcmQuRCIpCnBsb3QoZml0X2EpCnJlY3QuaGNsdXN0KGZpdF9hLCBrID0gNixib3JkZXIgPSAicmVkIikgIyBjdXQgdHJlZSBpbnRvIDYgY2x1c3RlcnMKYGBgCgojIyBMREEgVG9waWMgTW9kZWxsaW5nCgpgYGB7ciBMREEgQmFzaWNzLCBpbmNsdWRlPUZBTFNFfQpvcHRpb25zKG1jLmNvcmVzID0gMTApCnRtX3BhckxhcHBseV9lbmdpbmUocGFyYWxsZWw6Om1jbGFwcGx5KSAgIyBtY2xhcHBseSBnZXRzIHRoZSBudW1iZXIgb2YgY29yZXMgZnJvbSBnbG9iYWwgb3B0aW9ucwoKYGBgCgojIyMgU2Ftc3VuZyBTMjIKCmBgYHtyIExEQSBTYW1zdW5nLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIENyZWF0ZSBjb3JwdXMgb2JqZWN0CnNfY29ycHVzIDwtIENvcnB1cyhWZWN0b3JTb3VyY2UoYmdfZGZfcykpICAKCiMgUmVtb3ZlIEVuZ2xpc2ggc3RvcCB3b3Jkcy4Kc19jb3JwdXMgPC0gdG1fbWFwKHNfY29ycHVzLCByZW1vdmVXb3Jkcywgc3RvcHdvcmRzKCJlbiIpKSAgCgojIFJlbW92ZSBudW1iZXJzLgpzX2NvcnB1cyA8LSB0bV9tYXAoc19jb3JwdXMsIHJlbW92ZU51bWJlcnMpCgojIFN0ZW0gdGhlIHdvcmRzLgpzX2NvcnB1cyA8LSB0bV9tYXAoc19jb3JwdXMsIHN0ZW1Eb2N1bWVudCkKCiMgUmVtb3ZlIHRoZSBzdGVtcyBhc3NvY2lhdGVkIHdpdGggb3VyIHNlYXJjaCB0ZXJtcyEKc19jb3JwdXMgPC0gdG1fbWFwKHNfY29ycHVzLCByZW1vdmVXb3JkcywgYygiZ2FsYXhpIiwgInNhbXN1bmciLCAiZ2FsYXh5IiwgInVsdHJhIiwgIlwic2Ftc3VuZyIsICJcImdhbGF4eSIsICJpcGhvbmUiLCAiaXBob24iLCAiXCJpcGhvbiIsICJhcHBsIiwgInBybyIsICJtYXgiKSkKCnNfZG9jLmxlbmd0aHMgPC0gcm93U3Vtcyhhcy5tYXRyaXgoRG9jdW1lbnRUZXJtTWF0cml4KHNfY29ycHVzKSkpCnNfZHRtIDwtIERvY3VtZW50VGVybU1hdHJpeChzX2NvcnB1cykKCiMgTm93IGZvciBzb21lIHRvcGljcwpTRUVEID0gc2FtcGxlKDE6MTAwMDAwMCwgMSkgICMgUGljayBhIHJhbmRvbSBzZWVkIGZvciByZXBsaWNhdGlvbgprID0gNSAKCiMgVGhpcyBtaWdodCB0YWtlIGEgbWludXRlIQpzX21vZGVscyA8LSBsaXN0KAogIENUTSAgICAgICA9IENUTShzX2R0bSwgayA9IGssIGNvbnRyb2wgPSBsaXN0KHNlZWQgPSBTRUVELCB2YXIgPSBsaXN0KHRvbCA9IDEwXi00KSwgZW0gPSBsaXN0KHRvbCA9IDEwXi0zKSkpLAogIFZFTSAgICAgICA9IExEQShzX2R0bSwgayA9IGssIGNvbnRyb2wgPSBsaXN0KHNlZWQgPSBTRUVEKSksCiAgVkVNX0ZpeGVkID0gTERBKHNfZHRtLCBrID0gaywgY29udHJvbCA9IGxpc3QoZXN0aW1hdGUuYWxwaGEgPSBGQUxTRSwgc2VlZCA9IFNFRUQpKSwKICBHaWJicyAgICAgPSBMREEoc19kdG0sIGsgPSBrLCBtZXRob2QgPSAiR2liYnMiLCBjb250cm9sID0gbGlzdChzZWVkID0gU0VFRCwgYnVybmluID0gMTAwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpbiA9IDEwMCwgICAgaXRlciA9IDEwMDApKQopCgojIFRoZXJlIHlvdSBoYXZlIGl0LiBNb2RlbHMgbm93IGhvbGRzIDQgdG9waWNzLiBTZWUgdGhlIHRvcGljbW9kZWxzIEFQSSBkb2N1bWVudGF0aW9uIGZvciBkZXRhaWxzCgojIFRvcCAxMCB0ZXJtcyBvZiBlYWNoIHRvcGljIGZvciBlYWNoIG1vZGVsCiMgRG8geW91IHNlZSBhbnkgdGhlbWVzIHlvdSBjYW4gbGFiZWwgdG8gdGhlc2UgInRvcGljcyIgKGxpc3RzIG9mIHdvcmRzKT8KbGFwcGx5KHNfbW9kZWxzLCB0ZXJtcywgMTApCgpzX2Fzc2lnbm1lbnRzIDwtIHNhcHBseShzX21vZGVscywgdG9waWNzKSAKCnNfYXNzaWdubWVudHMKCgojIyMgc3RpbGwgbWlzc2luZzogZ3JhcGhzIGRlcGljdCB0aGUgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9ucyBmb3IgYWxsIHRoZSB0ZXJtcyBlYWNoIExEQSB0b3BpYyBoYXMgMTAgdGVybXMgd2hpY2ggaXMgaW5kZXBlbmRlbnQgb2YgdGVybXMgaW4gb3RoZXIgTERBIHRvcGljCmBgYAoKVGhlIHRvcGljcyBhYm91dCAic2VyaSIsICJub3ciLCAiY2FtZXJhIiwgInVwZGF0ZSIgcmVsYXRlcyB0byB0aGUgW1MyMiBVbHRyYSdzIEFwcmlsIHBhdGNoIHRoYXQgaW50cm9kdWNlZCBtYW55IGNhbWVyYS1yZWxhdGVkIGZlYXR1cmVzXShodHRwczovL3d3dy5hbmRyb2lkcG9saWNlLmNvbS9zYW1zdW5ncy1hcHJpbC0yMDIyLXNlY3VyaXR5LXVwZGF0ZS1pcy1hcnJpdmluZy1mb3ItZ2FsYXh5LW93bmVycy1pbi10aGUtdXMvKS4KCiMjIyBBcHBsZSBpUGhvbmUgMTMKCmBgYHtyIExEQSBBcHBsZSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBDcmVhdGUgY29ycHVzIG9iamVjdAphX2NvcnB1cyA8LSBDb3JwdXMoVmVjdG9yU291cmNlKGJnX2RmX2EpKSAgCgojIFJlbW92ZSBFbmdsaXNoIHN0b3Agd29yZHMuCmFfY29ycHVzIDwtIHRtX21hcChhX2NvcnB1cywgcmVtb3ZlV29yZHMsIHN0b3B3b3JkcygiZW4iKSkgIAoKIyBSZW1vdmUgbnVtYmVycy4KYV9jb3JwdXMgPC0gdG1fbWFwKGFfY29ycHVzLCByZW1vdmVOdW1iZXJzKQoKIyBTdGVtIHRoZSB3b3Jkcy4KYV9jb3JwdXMgPC0gdG1fbWFwKGFfY29ycHVzLCBzdGVtRG9jdW1lbnQpCgojIFJlbW92ZSB0aGUgc3RlbXMgYXNzb2NpYXRlZCB3aXRoIG91ciBzZWFyY2ggdGVybXMhCmFfY29ycHVzIDwtIHRtX21hcChhX2NvcnB1cywgcmVtb3ZlV29yZHMsIGMoImdhbGF4aSIsICJzYW1zdW5nIiwgImdhbGF4eSIsICJ1bHRyYSIsICJcInNhbXN1bmciLCAiXCJnYWxheHkiLCAiaXBob25lIiwgImlwaG9uIiwgIlwiaXBob24iLCAiYXBwbCIsICJwcm8iLCAibWF4IikpCgphX2RvYy5sZW5ndGhzIDwtIHJvd1N1bXMoYXMubWF0cml4KERvY3VtZW50VGVybU1hdHJpeChhX2NvcnB1cykpKQphX2R0bSA8LSBEb2N1bWVudFRlcm1NYXRyaXgoYV9jb3JwdXMpCgojIE5vdyBmb3Igc29tZSB0b3BpY3MKU0VFRCA9IHNhbXBsZSgxOjEwMDAwMDAsIDEpIAprID0gMTAKCiMgVGhpcyBtaWdodCB0YWtlIGEgbWludXRlIQphX21vZGVscyA8LSBsaXN0KAogIENUTSAgICAgICA9IENUTShhX2R0bSwgayA9IGssIGNvbnRyb2wgPSBsaXN0KHNlZWQgPSBTRUVELCB2YXIgPSBsaXN0KHRvbCA9IDEwXi00KSwgZW0gPSBsaXN0KHRvbCA9IDEwXi0zKSkpLAogIFZFTSAgICAgICA9IExEQShhX2R0bSwgayA9IGssIGNvbnRyb2wgPSBsaXN0KHNlZWQgPSBTRUVEKSksCiAgVkVNX0ZpeGVkID0gTERBKGFfZHRtLCBrID0gaywgY29udHJvbCA9IGxpc3QoZXN0aW1hdGUuYWxwaGEgPSBGQUxTRSwgc2VlZCA9IFNFRUQpKSwKICBHaWJicyAgICAgPSBMREEoYV9kdG0sIGsgPSBrLCBtZXRob2QgPSAiR2liYnMiLCBjb250cm9sID0gbGlzdChzZWVkID0gU0VFRCwgYnVybmluID0gMTAwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGluID0gMTAwLCAgICBpdGVyID0gMTAwMCkpCikKCiMgVG9wIDEwIHRlcm1zIG9mIGVhY2ggdG9waWMgZm9yIGVhY2ggbW9kZWwKIyBEbyB5b3Ugc2VlIGFueSB0aGVtZXMgeW91IGNhbiBsYWJlbCB0byB0aGVzZSAidG9waWNzIiAobGlzdHMgb2Ygd29yZHMpPwpsYXBwbHkoYV9tb2RlbHMsIHRlcm1zLCAxMCkKCmFfYXNzaWdubWVudHMgPC0gc2FwcGx5KGFfbW9kZWxzLCB0b3BpY3MpIAoKYV9hc3NpZ25tZW50cwoKCiMjIyBzdGlsbCBtaXNzaW5nOiBncmFwaHMgZGVwaWN0IHRoZSBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb25zIGZvciBhbGwgdGhlIHRlcm1zIGVhY2ggTERBIHRvcGljIGhhcyAxMCB0ZXJtcyB3aGljaCBpcyBpbmRlcGVuZGVudCBvZiB0ZXJtcyBpbiBvdGhlciBMREEgdG9waWMKYGBgCgojIEFtYXpvbiBSZXZpZXcgQW5hbHlzaXMKCmBgYHtyIEluaXRpYWxpc2luZyBQYWNrYWdlcyBBbWF6b24sIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHR3aXR0ZVIpCmxpYnJhcnkoUk9BdXRoKQpsaWJyYXJ5KGhtcykKbGlicmFyeShsdWJyaWRhdGUpIApsaWJyYXJ5KHRpZHl0ZXh0KQpsaWJyYXJ5KE5MUCkKbGlicmFyeSh0bSkKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkod29yZGNsb3VkKQpsaWJyYXJ5KGlncmFwaCkKbGlicmFyeShnbHVlKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShuZXR3b3JrRDMpCmxpYnJhcnkocnR3ZWV0KQpsaWJyYXJ5KHBseXIpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdnZWFzeSkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoZHBseXIpICAKbGlicmFyeShobXMpCmxpYnJhcnkobHVicmlkYXRlKSAKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkod2lkeXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkodGlkeXRleHQpCmxpYnJhcnkoYmFzZTY0ZW5jKQpgYGAKCiMjIERhdGEgSW5wdXQKCmBgYHtyIFJlYWQgZmlsZSBTYW1zdW5nLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQpzYW1zdW5nLnJldmlld3MgPC0gcmVhZC5jc3YoIlNhbXN1bmdfQW16LmNzdiIpCmlwaG9uZS5yZXZpZXdzIDwtIHJlYWQuY3N2KCJpUGhvbmVfQW16LmNzdiIpCmBgYAoKYGBge3IgSW5mb3JtYXRpb24gYWJvdXQgdGhlIGRhdGEsIGVjaG89RkFMU0V9CmRpbShzYW1zdW5nLnJldmlld3MpICNkaW1lbnNpb24gb2YgdGhlIGRhdGEKc3VtbWFyeShzYW1zdW5nLnJldmlld3MpCmRpbShpcGhvbmUucmV2aWV3cykKc3VtbWFyeShpcGhvbmUucmV2aWV3cykKYGBgCgojIyBEYXRhIFByZXByb2Nlc3NpbmcKCmBgYHtyIFByZXByb2Nlc3NpbmcgQW1hem9uIGRhdGEsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMgTG9hZCAiU3RvcCBXb3JkcyIgZnJvbSB0aGUgdGlkeXRleHQgcGFja2FnZQpkYXRhKCJzdG9wX3dvcmRzIikKCiMgUmVtb3ZpbmcgU3RvcCBXb3JkcyBpbiBib3RoIGRhdGEgZnJhbWVzCnNhbXN1bmcucmV2aWV3cy50ZXh0IDwtIHNhbXN1bmcucmV2aWV3cyAlPiUKICBzZWxlY3QocmV2aWV3X3RleHQpCgppcGhvbmUucmV2aWV3cy50ZXh0IDwtIGlwaG9uZS5yZXZpZXdzICU+JQogIHNlbGVjdChyZXZpZXdfdGV4dCkKCmxpYnJhcnkoc3RyaW5naSkKc3RyaV9lbmNfbWFyayhzYW1zdW5nLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCkKc2Ftc3VuZy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQgPC0gc2FwcGx5KHNhbXN1bmcucmV2aWV3cy50ZXh0JHJldmlld190ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihyb3cpIGljb252KHJvdywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibGF0aW4xIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQVNDSUkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9ICIgIikpCgojIExvd2VjYXNlIGFsbCB0ZXh0CnNhbXN1bmcucmV2aWV3cy50ZXh0JHJldmlld190ZXh0IDwtIHRvbG93ZXIoc2Ftc3VuZy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQpCgojIG1ha2Ugd2Fzbid0PXdhcyBub3QsIGNhbid0PWNhbiBub3QsIGV0Yy4uCnNhbXN1bmcucmV2aWV3cy50ZXh0JHJldmlld190ZXh0IDwtIGdzdWIoIndhc25bXHUyMDE5J110IiwgIndhcyBub3QiLCBzYW1zdW5nLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCkKc2Ftc3VuZy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQgPC0gZ3N1Yigid29uW1x1MjAxOSdddCIsICJ3aWxsIG5vdCIsIHNhbXN1bmcucmV2aWV3cy50ZXh0JHJldmlld190ZXh0KQpzYW1zdW5nLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCA8LSBnc3ViKCJjYW5bXHUyMDE5J110IiwgImNhbiBub3QiLCBzYW1zdW5nLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCkKc2Ftc3VuZy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQgPC0gZ3N1YigiZGlkbltcdTIwMTknXXQiLCAiZGlkIG5vdCIsIHNhbXN1bmcucmV2aWV3cy50ZXh0JHJldmlld190ZXh0KQpzYW1zdW5nLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCA8LSBnc3ViKCJkb25bXHUyMDE5J110IiwgImRvIG5vdCIsIHNhbXN1bmcucmV2aWV3cy50ZXh0JHJldmlld190ZXh0KQpzYW1zdW5nLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCA8LSBnc3ViKCJJW1x1MjAxOSddbSIsICJJIGFtIiwgc2Ftc3VuZy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQpCnNhbXN1bmcucmV2aWV3cy50ZXh0JHJldmlld190ZXh0IDwtIGdzdWIoIltcdTIwMTknXXZlIiwgIiBoYXZlIiwgc2Ftc3VuZy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQpIApzYW1zdW5nLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCA8LSBnc3ViKCJbXHUyMDE5fCddcyIsICIiLCBzYW1zdW5nLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCkKc2Ftc3VuZy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQgPC0gZ3N1YigiW1x1MjAxOSddcmUiLCAiIGFyZSIsIHNhbXN1bmcucmV2aWV3cy50ZXh0JHJldmlld190ZXh0KQpzYW1zdW5nLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCA8LSBnc3ViKCJbXHUyMDE5J11sbCIsICIgd2lsbCIsIHNhbXN1bmcucmV2aWV3cy50ZXh0JHJldmlld190ZXh0KQoKCiMgSWYgeW91IHZpZXcgY29tbW9uIHR5cG9zIGR1cmluZyB5b3VyIGFuYWx5c2lzLCBmaXggdGhlbSBoZXJlLgpzYW1zdW5nLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dDwtIGdzdWIoImNhbmNlbGluZyIsICJjYW5jZWxsaW5nIiwgc2Ftc3VuZy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQpCnNhbXN1bmcucmV2aWV3cy50ZXh0JHJldmlld190ZXh0IDwtIGdzdWIoImNhbmNlbGxhdGlvbiIsICJjYW5jZWxsaW5nIiwgc2Ftc3VuZy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQpCnNhbXN1bmcucmV2aWV3cy50ZXh0JHJldmlld190ZXh0IDwtIGdzdWIoImlzc3VlcyIsICJpc3N1ZSIsIHNhbXN1bmcucmV2aWV3cy50ZXh0JHJldmlld190ZXh0KQoKIyBvbWl0IHRoZSBmb2xsb3dpbmcgdHdvIGxpbmVzIGlmIHlvdSBoYXZlIG5vdCBsb2FkZWQgdGhlIHRtIHBhY2thZ2UKIyBSZW1vdmUgbnVtYmVycyBpbiB0aGUgdGV4dAojYm9zZS5oZWFkcGhvbmVzLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCA8LSByZW1vdmVOdW1iZXJzKGJvc2UuaGVhZHBob25lcy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQpCgojIFJlbW92ZSBwdW5jdHVhdGlvbnMgaW4gdGhlIHRleHQKc2Ftc3VuZy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQgPC0gcmVtb3ZlUHVuY3R1YXRpb24oc2Ftc3VuZy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQpCgojIEZpeCBOZWdhdGlvbnMKIyBDcmVhdGUgYSBsaXN0IHRvIGlkZW50aWZ5IHRoZSBzZW50aW1lbnQgc2hpZnRlcnMgaW4gdGhlIHRleHQKbmVnYXRpb24ud29yZHMgPC0gYygibm90IiwKICAgICAgICAgICAgICAgICAgICAibm8iLAogICAgICAgICAgICAgICAgICAgICJ3aXRob3V0IiwKICAgICAgICAgICAgICAgICAgICAibmV2ZXIiLAogICAgICAgICAgICAgICAgICAgICJiYWQiLAogICAgICAgICAgICAgICAgICAgICJub25lIiwKICAgICAgICAgICAgICAgICAgICAibmV2ZXIiLAogICAgICAgICAgICAgICAgICAgICJub2JvZHkiLAogICAgICAgICAgICAgICAgICAgICJub3doZXJlIiwKICAgICAgICAgICAgICAgICAgICAibmVpdGhlciIsCiAgICAgICAgICAgICAgICAgICAgIm5vdGhpbmciCikKCnN0cmlfZW5jX21hcmsoaXBob25lLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCkKaXBob25lLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCA8LSBzYXBwbHkoaXBob25lLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihyb3cpIGljb252KHJvdywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsYXRpbjEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFTQ0lJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YiA9ICIgIikpCgojIExvd2VjYXNlIGFsbCB0ZXh0CmlwaG9uZS5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQgPC0gdG9sb3dlcihpcGhvbmUucmV2aWV3cy50ZXh0JHJldmlld190ZXh0KQoKIyBtYWtlIHdhc24ndD13YXMgbm90LCBjYW4ndD1jYW4gbm90LCBldGMuLgppcGhvbmUucmV2aWV3cy50ZXh0JHJldmlld190ZXh0IDwtIGdzdWIoIndhc25bXHUyMDE5J110IiwgIndhcyBub3QiLCBpcGhvbmUucmV2aWV3cy50ZXh0JHJldmlld190ZXh0KQppcGhvbmUucmV2aWV3cy50ZXh0JHJldmlld190ZXh0IDwtIGdzdWIoIndvbltcdTIwMTknXXQiLCAid2lsbCBub3QiLCBpcGhvbmUucmV2aWV3cy50ZXh0JHJldmlld190ZXh0KQppcGhvbmUucmV2aWV3cy50ZXh0JHJldmlld190ZXh0IDwtIGdzdWIoImNhbltcdTIwMTknXXQiLCAiY2FuIG5vdCIsIGlwaG9uZS5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQpCmlwaG9uZS5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQgPC0gZ3N1YigiZGlkbltcdTIwMTknXXQiLCAiZGlkIG5vdCIsIGlwaG9uZS5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQpCmlwaG9uZS5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQgPC0gZ3N1YigiZG9uW1x1MjAxOSdddCIsICJkbyBub3QiLCBpcGhvbmUucmV2aWV3cy50ZXh0JHJldmlld190ZXh0KQppcGhvbmUucmV2aWV3cy50ZXh0JHJldmlld190ZXh0IDwtIGdzdWIoIklbXHUyMDE5J11tIiwgIkkgYW0iLCBpcGhvbmUucmV2aWV3cy50ZXh0JHJldmlld190ZXh0KQppcGhvbmUucmV2aWV3cy50ZXh0JHJldmlld190ZXh0IDwtIGdzdWIoIltcdTIwMTknXXZlIiwgIiBoYXZlIiwgaXBob25lLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCkgCmlwaG9uZS5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQgPC0gZ3N1YigiW1x1MjAxOXwnXXMiLCAiIiwgaXBob25lLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCkKaXBob25lLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCA8LSBnc3ViKCJbXHUyMDE5J11yZSIsICIgYXJlIiwgaXBob25lLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCkKaXBob25lLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCA8LSBnc3ViKCJbXHUyMDE5J11sbCIsICIgd2lsbCIsIGlwaG9uZS5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQpCgoKIyBJZiB5b3UgdmlldyBjb21tb24gdHlwb3MgZHVyaW5nIHlvdXIgYW5hbHlzaXMsIGZpeCB0aGVtIGhlcmUuCmlwaG9uZS5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQ8LSBnc3ViKCJjYW5jZWxpbmciLCAiY2FuY2VsbGluZyIsIGlwaG9uZS5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQpCmlwaG9uZS5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQgPC0gZ3N1YigiY2FuY2VsbGF0aW9uIiwgImNhbmNlbGxpbmciLCBpcGhvbmUucmV2aWV3cy50ZXh0JHJldmlld190ZXh0KQoKIyBSZW1vdmUgcHVuY3R1YXRpb25zIGluIHRoZSB0ZXh0CmlwaG9uZS5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQgPC0gcmVtb3ZlUHVuY3R1YXRpb24oaXBob25lLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCkKCmBgYAoKYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kc2hpZnRlZC53b3JkcyA8LSBzYW1zdW5nLnJldmlld3MudGV4dCAlPiUKICB1bm5lc3RfdG9rZW5zKGJpZ3JhbSwgcmV2aWV3X3RleHQsIHRva2VuID0gIm5ncmFtcyIsIG4gPSAyKSU+JQogIGRwbHlyOjpjb3VudChiaWdyYW0sIHNvcnQgPSBUUlVFKSAlPiUKICBzZXBhcmF0ZShiaWdyYW0sIGMoIndvcmQxIiwgIndvcmQyIiksIHNlcCA9ICIgIiklPiUKICBmaWx0ZXIod29yZDEgJWluJSBuZWdhdGlvbi53b3JkcyAmICF3b3JkMiAlaW4lIHN0b3Bfd29yZHMkd29yZCklPiUKICBpbm5lcl9qb2luKGdldF9zZW50aW1lbnRzKCJiaW5nIiksIGJ5ID0gYyh3b3JkMiA9ICJ3b3JkIikpJT4lCiAgbXV0YXRlKHNlbnRpbWVudCA9IGlmZWxzZShzZW50aW1lbnQgPT0gInBvc2l0aXZlIiwgMSwgLTEpKSAlPiUKICBtdXRhdGUoc2NvcmUgPSBzZW50aW1lbnQgKiBuKSAlPiUKICBtdXRhdGUod29yZDIgPSByZW9yZGVyKHdvcmQyLCBzY29yZSkpCgpzaGlmdGVkLndvcmRzCgojIFBpY2sgdGhlIG1vc3QgZWZmZWN0aXZlIHNlbnRpbWVudCBzaGlmdGVycwpuZWdhdGVkLnBocmFzZXMgPC0gYygibm90IHdvcnRoIiwgCiAgICAgICAgICAgICAgICAgICAgICJub3Qgbm9pc2UiLAogICAgICAgICAgICAgICAgICAgICAibm8gaXNzdWVzIiwKICAgICAgICAgICAgICAgICAgICAgIm5vIGNvbXBsYWludHMiLAogICAgICAgICAgICAgICAgICAgICAibm90IGRpc2FwcG9pbnQiLAogICAgICAgICAgICAgICAgICAgICAibm90IGRpc2FwcG9pbnRlZCIsCiAgICAgICAgICAgICAgICAgICAgICJub3QgY2hlYXAiLAogICAgICAgICAgICAgICAgICAgICAibm8gcmVncmV0cyIKICAgICAgICAgICAgICAgICAgICAgCikKCiMgRmluZCBzeW5vbnltcyBmb3IgdGhlIHBocmFzZXMgYWJvdmUgdG8gcmVwbGFjZQpzeW5vbnltcyA8LSBjKCJleHBlbnNpdmUiLAogICAgICAgICAgICAgICJmdW5jdGlvbmFsIiwKICAgICAgICAgICAgICAiY29vbCIsCiAgICAgICAgICAgICAgInNhdGlzZmllZCIsCiAgICAgICAgICAgICAgInNhdGlzZmllZCIsCiAgICAgICAgICAgICAgInNhdGlzZmllZCIsCiAgICAgICAgICAgICAgImV4cGVuc2l2ZSIsCiAgICAgICAgICAgICAgInNhdGlzZmllZCIKKQpsaWJyYXJ5KHRleHRjbGVhbikKIyBSZXBsYWNlIHRoZSBuZWdhdGlvbnMgd2l0aCB0aGVpciBzeW5vbnltcy4Kc2Ftc3VuZy5yZXZpZXdzLnRleHQgPC0gbWdzdWIoc2Ftc3VuZy5yZXZpZXdzLnRleHQkcmV2aWV3X3RleHQsIG5lZ2F0ZWQucGhyYXNlcywgc3lub255bXMpICU+JQogIGRwbHlyOjphc19kYXRhX2ZyYW1lKCkgJT4lCiAgcmVuYW1lKHJldmlld190ZXh0ID0gdmFsdWUpCgpzYW1zdW5nLnJldmlld3MudGV4dAoKYGBgCgpgYGB7cn0Kc2hpZnRlZC53b3JkcyA8LSBpcGhvbmUucmV2aWV3cy50ZXh0ICU+JQogIHVubmVzdF90b2tlbnMoYmlncmFtLCByZXZpZXdfdGV4dCwgdG9rZW4gPSAibmdyYW1zIiwgbiA9IDIpJT4lCiAgZHBseXI6OmNvdW50KGJpZ3JhbSwgc29ydCA9IFRSVUUpICU+JQogIHNlcGFyYXRlKGJpZ3JhbSwgYygid29yZDEiLCAid29yZDIiKSwgc2VwID0gIiAiKSU+JQogIGZpbHRlcih3b3JkMSAlaW4lIG5lZ2F0aW9uLndvcmRzICYgIXdvcmQyICVpbiUgc3RvcF93b3JkcyR3b3JkKSU+JQogIGlubmVyX2pvaW4oZ2V0X3NlbnRpbWVudHMoImJpbmciKSwgYnkgPSBjKHdvcmQyID0gIndvcmQiKSklPiUKICBtdXRhdGUoc2VudGltZW50ID0gaWZlbHNlKHNlbnRpbWVudCA9PSAicG9zaXRpdmUiLCAxLCAtMSkpICU+JQogIG11dGF0ZShzY29yZSA9IHNlbnRpbWVudCAqIG4pICU+JQogIG11dGF0ZSh3b3JkMiA9IHJlb3JkZXIod29yZDIsIHNjb3JlKSkKCnNoaWZ0ZWQud29yZHMKCmlwaG9uZS5yZXZpZXdzLnRleHQgPC0gbWdzdWIoaXBob25lLnJldmlld3MudGV4dCRyZXZpZXdfdGV4dCwgbmVnYXRlZC5waHJhc2VzLCBzeW5vbnltcykgJT4lCiAgZHBseXI6OmFzX2RhdGFfZnJhbWUoKSAlPiUKICByZW5hbWUocmV2aWV3X3RleHQgPSB2YWx1ZSkKCmlwaG9uZS5yZXZpZXdzLnRleHQKYGBgCgojIyBXb3JkY2xvdWQKCmBgYHtyIFNhbXN1bmcgV29yZGNsb3VkIEFtYXpvbiwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBpZiB5b3Ugd2FudCB0byBpZ25vcmUgd29yZHMgdGhhdCBhcmUgZnJlcXVlbnQgYnV0IGRvZXNuJ3QgaGVscCwgYWRkIHRoZW0gdG8gdGhpcyBsaXN0LiAjIyNJZ25vcmUgdGhlIHdvcmRzCmlnbm9yZS53b3JkcyA8LSBkYXRhX2ZyYW1lKHdvcmQgPSBjKCAic2Ftc3VuZyIsInBob25lIikpCgojIGNyZWF0ZSB0aGUgd29yZHMgZnJlcSB0YWJsZQp3b3JkLmZyZXEudGFibGVfcyA8LSBzYW1zdW5nLnJldmlld3MudGV4dCAlPiUgCiAgdW5uZXN0X3Rva2Vucyh3b3JkLCByZXZpZXdfdGV4dCkgJT4lCiAgYW50aV9qb2luKHN0b3Bfd29yZHMpICU+JQogIGFudGlfam9pbihpZ25vcmUud29yZHMpICU+JQogIGRwbHlyOjpjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkKd29yZC5mcmVxLnRhYmxlX3MKCiMgUGxvdHRpbmcgYSBXb3JkY2xvdWQKd29yZC5mcmVxLnRhYmxlX3MgJT4lIAogIGZpbHRlcihuPjgpICU+JQogIHdpdGgod29yZGNsb3VkKHdvcmQsIG4sCiAgICAgICAgICAgICAgICAgc2NhbGUgPSBjKDUsMC4zKSwKICAgICAgICAgICAgICAgICBjb2xvcnMgPSBicmV3ZXIucGFsKDgsICJEYXJrMiIpKSkKCmBgYAoKYGBge3IgV29yZGNsb3VkIEFwcGxlIEFtYXpvbiwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBpZiB5b3Ugd2FudCB0byBpZ25vcmUgd29yZHMgdGhhdCBhcmUgZnJlcXVlbnQgYnV0IGRvZXNuJ3QgaGVscCwgYWRkIHRoZW0gdG8gdGhpcyBsaXN0LiAjIyNJZ25vcmUgdGhlIHdvcmRzCmlnbm9yZS53b3JkcyA8LSBkYXRhX2ZyYW1lKHdvcmQgPSBjKCJpcGhvbmUiLCAicGhvbmUiLCJhcHBsZSIsICIxMyIpKQoKIyBjcmVhdGUgdGhlIHdvcmRzIGZyZXEgdGFibGUKd29yZC5mcmVxLnRhYmxlX2E8LSBpcGhvbmUucmV2aWV3cy50ZXh0ICU+JSAKICB1bm5lc3RfdG9rZW5zKHdvcmQsIHJldmlld190ZXh0KSAlPiUKICBhbnRpX2pvaW4oc3RvcF93b3JkcykgJT4lCiAgYW50aV9qb2luKGlnbm9yZS53b3JkcykgJT4lCiAgZHBseXI6OmNvdW50KHdvcmQsIHNvcnQgPSBUUlVFKQp3b3JkLmZyZXEudGFibGVfYQoKIyBQbG90dGluZyBhIFdvcmRjbG91ZAp3b3JkLmZyZXEudGFibGVfYSAlPiUgCiAgZmlsdGVyKG4+OCkgJT4lCiAgd2l0aCh3b3JkY2xvdWQod29yZCwgbiwKICAgICAgICAgICAgICAgICBzY2FsZSA9IGMoNSwwLjMpLAogICAgICAgICAgICAgICAgIGNvbG9ycyA9IGJyZXdlci5wYWwoOCwgIkRhcmsyIikpKQoKYGBgCgojIyBTZW50aW1lbnQgQW5hbHlzaXMKCmBgYHtyIFBvc2l0aXZlIGFuZCBuZWdhdGl2ZSB3b3JkcyBBbWF6b24gU2Ftc3VuZywgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBNb3N0IGNvbW1vbiBQb3NpdGl2ZSBhbmQgTmVnYXRpdmUgd29yZHMgdXNpbmcgQmluZwpzYW1zdW5nLnJldmlld3MudGV4dCAlPiUgCiAgdW5uZXN0X3Rva2Vucyh3b3JkLCByZXZpZXdfdGV4dCkgJT4lCiAgYW50aV9qb2luKHN0b3Bfd29yZHMpICU+JQogIGFudGlfam9pbihpZ25vcmUud29yZHMpICU+JQogIGlubmVyX2pvaW4oZ2V0X3NlbnRpbWVudHMoImJpbmciKSkgJT4lCiAgZHBseXI6OmNvdW50KHdvcmQsIHNlbnRpbWVudCwgc29ydCA9IFRSVUUpICU+JQogIGZpbHRlcihuID4gMikgJT4lCiAgbXV0YXRlKHdvcmQgPSByZW9yZGVyKHdvcmQsIG4pKSAlPiUKICBtdXRhdGUocGVyY2VudCA9IHJvdW5kKG4vc3VtKG4pLCAzKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gd29yZCwgeSA9IHBlcmNlbnQsIGZpbGwgPSBzZW50aW1lbnQsIGxhYmVsID0gcGVyY2VudCkpICsKICBnZW9tX2NvbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZmFjZXRfd3JhcCh+c2VudGltZW50LCBzY2FsZXMgPSAiZnJlZV95IikgKwogIGdlb21fdGV4dChhZXMoeSA9IDAuNypwZXJjZW50KSkgKwogIGxhYnModGl0bGUgPSAiU2Ftc3VuZyBQb2xhcml0eSAoYmluZykiKSArCiAgY29vcmRfZmxpcCgpICsgCiAgdGhlbWVfYncoKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCgpgYGAKCmBgYHtyIFBvc2l0aXZlIGFuZCBuZWdhdGl2ZSB3b3JkcyBBbWF6b24gQXBwbGUsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgTW9zdCBjb21tb24gUG9zaXRpdmUgYW5kIE5lZ2F0aXZlIHdvcmRzIHVzaW5nIEJpbmcKaXBob25lLnJldmlld3MudGV4dCAlPiUgCiAgdW5uZXN0X3Rva2Vucyh3b3JkLCByZXZpZXdfdGV4dCkgJT4lCiAgYW50aV9qb2luKHN0b3Bfd29yZHMpICU+JQogIGFudGlfam9pbihpZ25vcmUud29yZHMpICU+JQogIGlubmVyX2pvaW4oZ2V0X3NlbnRpbWVudHMoImJpbmciKSkgJT4lCiAgZHBseXI6OmNvdW50KHdvcmQsIHNlbnRpbWVudCwgc29ydCA9IFRSVUUpICU+JQogIGZpbHRlcihuID4gMikgJT4lCiAgbXV0YXRlKHdvcmQgPSByZW9yZGVyKHdvcmQsIG4pKSAlPiUKICBtdXRhdGUocGVyY2VudCA9IHJvdW5kKG4vc3VtKG4pLCAzKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gd29yZCwgeSA9IHBlcmNlbnQsIGZpbGwgPSBzZW50aW1lbnQsIGxhYmVsID0gcGVyY2VudCkpICsKICBnZW9tX2NvbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZmFjZXRfd3JhcCh+c2VudGltZW50LCBzY2FsZXMgPSAiZnJlZV95IikgKwogIGdlb21fdGV4dChhZXMoeSA9IDAuNypwZXJjZW50KSkgKwogIGxhYnModGl0bGUgPSAiaVBob25lIDEzIFdvcmQgUG9sYXJpdHkgKGJpbmcpIikgKwogIGNvb3JkX2ZsaXAoKSArIAogIHRoZW1lX2J3KCkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQoKYGBgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIEJpbmcgU2Ftc3VuZwpiaW5nLm1lYW4uc2NvcmVfcyA8LSB3b3JkLmZyZXEudGFibGVfcyAlPiUgCiAgaW5uZXJfam9pbihnZXRfc2VudGltZW50cygiYmluZyIpKSAlPiUKICBtdXRhdGUoc2VudGltZW50ID0gaWZlbHNlKHNlbnRpbWVudCA9PSAicG9zaXRpdmUiLCAxLCAtMSkpICU+JQogIHN1bW1hcmlzZShTYW1zdW5nX21lYW4gPSBtZWFuKHNlbnRpbWVudCkpCgpiaW5nLm1lYW4uc2NvcmVfYSA8LSB3b3JkLmZyZXEudGFibGVfYSAlPiUgCiAgaW5uZXJfam9pbihnZXRfc2VudGltZW50cygiYmluZyIpKSAlPiUKICBtdXRhdGUoc2VudGltZW50ID0gaWZlbHNlKHNlbnRpbWVudCA9PSAicG9zaXRpdmUiLCAxLCAtMSkpICU+JQogIHN1bW1hcmlzZShBcHBsZV9tZWFuID0gbWVhbihzZW50aW1lbnQpKQoKZGF0YS5mcmFtZShiaW5nLm1lYW4uc2NvcmVfcywgYmluZy5tZWFuLnNjb3JlX2EpCgpgYGAKCmBgYHtyfQojU2Ftc3VuZwojIHJlc2NhbGUgdGhlIHJhbmdlIHRvIDUgc3RhciByYW5nZS4KYmluZy5tZWFuLnNjb3JlX3M8LXJlc2NhbGUoYmluZy5tZWFuLnNjb3JlX3MkbWVhbiwgdG8gPSBjKDEsNSksIGZyb20gPSBjKC0xLDEpKQoKIyBBZmlubiBzY29yZXMgYXJlIGZyb20gLTUgdG8gNS4KYWZpbm4ubWVhbi5zY29yZV9zIDwtIHdvcmQuZnJlcS50YWJsZV9zICU+JSAKICBpbm5lcl9qb2luKGdldF9zZW50aW1lbnRzKCJhZmlubiIpKSU+JQogIHN1bW1hcmlzZShTYW1zdW5nX21lYW4gPSBtZWFuKHZhbHVlKSkKCiMgcmVzY2FsZSB0aGUgcmFuZ2UgdG8gNSBzdGFyIHJhbmdlLgphZmlubi5tZWFuLnNjb3JlX3M8LXJlc2NhbGUoYWZpbm4ubWVhbi5zY29yZV9zJFNhbXN1bmdfbWVhbiwgdG8gPSBjKDEsNSksIGZyb20gPSBjKC01LDUpKQoKI0FwcGxlCiMgcmVzY2FsZSB0aGUgcmFuZ2UgdG8gNSBzdGFyIHJhbmdlLgpiaW5nLm1lYW4uc2NvcmVfYTwtcmVzY2FsZShiaW5nLm1lYW4uc2NvcmVfYSRtZWFuLCB0byA9IGMoMSw1KSwgZnJvbSA9IGMoLTEsMSkpCgojIEFmaW5uIHNjb3JlcyBhcmUgZnJvbSAtNSB0byA1LgphZmlubi5tZWFuLnNjb3JlX2EgPC0gd29yZC5mcmVxLnRhYmxlX2EgJT4lIAogIGlubmVyX2pvaW4oZ2V0X3NlbnRpbWVudHMoImFmaW5uIikpJT4lCiAgc3VtbWFyaXNlKEFwcGxlX21lYW4gPSBtZWFuKHZhbHVlKSkKCiMgcmVzY2FsZSB0aGUgcmFuZ2UgdG8gNSBzdGFyIHJhbmdlLgphZmlubi5tZWFuLnNjb3JlX2E8LXJlc2NhbGUoYWZpbm4ubWVhbi5zY29yZV9hJEFwcGxlX21lYW4sIHRvID0gYygxLDUpLCBmcm9tID0gYygtNSw1KSkKYWZpbm4ubWVhbi5zY29yZV9hCgpkYXRhLnRhYmxlKGFmaW5uLm1lYW4uc2NvcmVfcywgYWZpbm4ubWVhbi5zY29yZV9hKQpgYGAKCiMjIFdvcmQgQ29ycmVsYXRpb24KCmBgYHtyfQojIENvcnJlbGF0aW9uIFRlcm1zCiMgVGhlIGNvcnJlbGF0aW9uIG9mIGFwcGVhcmluZyB0b2dldGhlciBpbiBhIHJldmlldwpzYW1zdW5nLmNvcnJlbGF0aW9uLnRlcm1zIDwtIHNhbXN1bmcucmV2aWV3cy50ZXh0ICU+JQogIG11dGF0ZShyZXZpZXcgPSByb3dfbnVtYmVyKCkpICU+JQogIHVubmVzdF90b2tlbnMod29yZCwgcmV2aWV3X3RleHQpICU+JQogIGZpbHRlcighd29yZCAlaW4lIHN0b3Bfd29yZHMkd29yZCkgJT4lCiAgZ3JvdXBfYnkod29yZCkgJT4lCiAgZmlsdGVyKG4oKSA+PTcpJT4lCiAgcGFpcndpc2VfY29yKHdvcmQsIHJldmlldywgc29ydCA9IFRSVUUpCnNhbXN1bmcuY29ycmVsYXRpb24udGVybXMKCmxpYnJhcnkoZ2dyYXBoKQpsaWJyYXJ5KGlncmFwaCkKc2Ftc3VuZy5jb3JyZWxhdGlvbi50ZXJtcyAlPiUKICBmaWx0ZXIoY29ycmVsYXRpb24gPj0gMC41MCkgJT4lCiAgZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKCkgJT4lCiAgZ2dyYXBoKGxheW91dCA9ICJpZ3JhcGgiLCBhbGdvcml0aG0gPSAia2siKSArCiAgZ2VvbV9lZGdlX2xpbmsoYWVzKGFscGhhID0gY29ycmVsYXRpb24pLCAKICAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFKSsKICBnZW9tX25vZGVfcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIiwgc2l6ZSA9IDIpICsKICBnZW9tX25vZGVfdGV4dChhZXMobGFiZWwgPSBuYW1lKSwgcmVwZWwgPSBUUlVFKSArCiAgdGhlbWVfdm9pZCgpKwogIGdndGl0bGUoIkNvcnJlbGF0aW9uIG9mIHRlcm1zIGluIFNhbXN1bmcgUzIyIFJldmlld3MiKQpgYGAKCmBgYHtyfQojIENvcnJlbGF0aW9uIFRlcm1zCiMgVGhlIGNvcnJlbGF0aW9uIG9mIGFwcGVhcmluZyB0b2dldGhlciBpbiBhIHJldmlldwphcHBsZS5jb3JyZWxhdGlvbi50ZXJtcyA8LSBpcGhvbmUucmV2aWV3cy50ZXh0ICU+JQogIG11dGF0ZShyZXZpZXcgPSByb3dfbnVtYmVyKCkpICU+JQogIHVubmVzdF90b2tlbnMod29yZCwgcmV2aWV3X3RleHQpICU+JQogIGZpbHRlcighd29yZCAlaW4lIHN0b3Bfd29yZHMkd29yZCkgJT4lCiAgZ3JvdXBfYnkod29yZCkgJT4lCiAgZmlsdGVyKG4oKSA+PSA1KSU+JQogIHBhaXJ3aXNlX2Nvcih3b3JkLCByZXZpZXcsIHNvcnQgPSBUUlVFKQphcHBsZS5jb3JyZWxhdGlvbi50ZXJtcwoKbGlicmFyeShnZ3JhcGgpCmxpYnJhcnkoaWdyYXBoKQphcHBsZS5jb3JyZWxhdGlvbi50ZXJtcyAlPiUKICBmaWx0ZXIoY29ycmVsYXRpb24gPj0gMC41MCkgJT4lCiAgZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKCkgJT4lCiAgZ2dyYXBoKGxheW91dCA9ICJpZ3JhcGgiLCBhbGdvcml0aG0gPSAia2siKSArCiAgZ2VvbV9lZGdlX2xpbmsoYWVzKGFscGhhID0gY29ycmVsYXRpb24pLCAKICAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFKSsKICBnZW9tX25vZGVfcG9pbnQoY29sb3IgPSAibGlnaHRibHVlIiwgc2l6ZSA9IDIpICsKICBnZW9tX25vZGVfdGV4dChhZXMobGFiZWwgPSBuYW1lKSwgcmVwZWwgPSBUUlVFKSArCiAgdGhlbWVfdm9pZCgpKwogIGdndGl0bGUoIkNvcnJlbGF0aW9uIG9mIHRlcm1zIGluIEFwcGxlIGlQaG9uZSAxMyBSZXZpZXdzIikKCmBgYAoKYGBge3J9CmJpZ3JhbXMubmV0d29yay5kZl9zIDwtIHNhbXN1bmcucmV2aWV3cy50ZXh0ICU+JQogIHVubmVzdF90b2tlbnMoYmlncmFtLCByZXZpZXdfdGV4dCwgdG9rZW4gPSAibmdyYW1zIiwgbiA9IDIpICU+JQogIHNlcGFyYXRlKGJpZ3JhbSwgYygid29yZDEiLCAid29yZDIiKSwgc2VwID0gIiAiKSAlPiUKICBmaWx0ZXIoIXdvcmQxICVpbiUgc3RvcF93b3JkcyR3b3JkICYgIXdvcmQyICVpbiUgc3RvcF93b3JkcyR3b3JkKSAlPiUKICBkcGx5cjo6Y291bnQod29yZDEsIHdvcmQyLCBzb3J0ID0gVFJVRSkgJT4lCiAgZmlsdGVyKG4gPiA1KQoKYmlncmFtcy5uZXR3b3JrX3MgPC0gZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKGJpZ3JhbXMubmV0d29yay5kZl9zKQpiaWdyYW1zLm5ldHdvcmtfcwoKYmlncmFtcy5uZXR3b3JrLmRmX2EgPC1pcGhvbmUucmV2aWV3cy50ZXh0ICU+JQogIHVubmVzdF90b2tlbnMoYmlncmFtLCByZXZpZXdfdGV4dCwgdG9rZW4gPSAibmdyYW1zIiwgbiA9IDIpICU+JQogIHNlcGFyYXRlKGJpZ3JhbSwgYygid29yZDEiLCAid29yZDIiKSwgc2VwID0gIiAiKSAlPiUKICBmaWx0ZXIoIXdvcmQxICVpbiUgc3RvcF93b3JkcyR3b3JkICYgIXdvcmQyICVpbiUgc3RvcF93b3JkcyR3b3JkKSAlPiUKICBkcGx5cjo6Y291bnQod29yZDEsIHdvcmQyLCBzb3J0ID0gVFJVRSkgJT4lCiAgZmlsdGVyKG4gPiAyKQoKYmlncmFtcy5uZXR3b3JrX2EgPC0gZ3JhcGhfZnJvbV9kYXRhX2ZyYW1lKGJpZ3JhbXMubmV0d29yay5kZl9hKQpiaWdyYW1zLm5ldHdvcmtfYQpgYGAKCmBgYHtyfQojIG5vdyB3ZSBmaW5kIHRoZSBjZW50cmFsaXR5IG1lYXN1cmVzIG9mIHRoZSBuZXR3b3JrCiMgZGVncmVlOnRoZSBudW1iZXIgb2YgaXRzIGFkamFjZW50IGVkZ2VzIChtZWFzdXJlIG9mIGRpcmVjdCBpbmZsdWVuY2UpCmRlZ19zIDwtIGRlZ3JlZShiaWdyYW1zLm5ldHdvcmtfcywgbW9kZSA9ICJhbGwiKQoKI0stY29yZSBkZWNvbXBvc2l0aW9uIGFsbG93cyB1cyB0byBpZGVudGlmeSB0aGUgY29yZSBhbmQgdGhlIHBlcmlwaGVyeSBvZiB0aGUgbmV0d29yay4gQSBrLWNvcmUgaXMgYSBtYXhpbWFsIHN1Ym5ldCBvZiBhIG5ldHdvcmsgc3VjaCB0aGF0IGFsbCBub2RlcyBoYXZlIGF0IGxlYXN0IGRlZ3JlZSBLLgpjb3JlX3MgPC0gY29yZW5lc3MoYmlncmFtcy5uZXR3b3JrX3MsIG1vZGUgPSAiYWxsIikKCiMgYmV0d2Vlbm5lc3MgbWVhc3VyZXMgYnJva2VyYWdlIG9yIGdhdGVrZWVwaW5nIHBvdGVudGlhbC4gSXQgaXMgKGFwcHJveGltYXRlbHkpIHRoZSBudW1iZXIgb2Ygc2hvcnRlc3QgcGF0aHMgYmV0d2VlbiBub2RlcyB0aGF0IHBhc3MgdGhyb3VnaCBhIHBhcnRpY3VsYXIgbm9kZS4KYmV0d19zIDwtIGJldHdlZW5uZXNzKGJpZ3JhbXMubmV0d29ya19zKQoKI0VpZ2VudmVjdG9yIGNlbnRyYWxpdHkgaXMgYSBtZWFzdXJlIG9mIGJlaW5nIHdlbGwtY29ubmVjdGVkIGNvbm5lY3RlZCB0byB0aGUgd2VsbC1jb25uZWN0ZWQuIEZpcnN0IGVpZ2VudmVjdG9yIG9mIHRoZSBncmFwaCBhZGphY2VuY3kgbWF0cml4LiBPbmx5IHdvcmtzIHdpdGggdW5kaXJlY3RlZCBuZXR3b3Jrcy4KZWlnZW5fcyA8LSBlaWdlbl9jZW50cmFsaXR5KGJpZ3JhbXMubmV0d29ya19zLCBkaXJlY3RlZCA9IFRSVUUpCm1lbWJlcnNfcyA8LSBjbHVzdGVyX3dhbGt0cmFwKGJpZ3JhbXMubmV0d29ya19zKQoKbGlicmFyeShpZ3JhcGgpCmJpZ3JhbXMubmV0d29ya19zIDwtIHNpbXBsaWZ5KGJpZ3JhbXMubmV0d29ya19zCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjcmVtb3ZlLm11bHRpcGxlID0gRkFMU0UsICNlcnJvciBvY2N1cmVkID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICNyZW1vdmUubG9vcHMgPSBUUlVFKQopClYoYmlncmFtcy5uZXR3b3JrX3MpJGNvbG9yIDwtIG1lbWJlcnMkbWVtYmVyc2hpcCsxCgpgYGAKCmBgYHtyfQojIG5vdyB3ZSBmaW5kIHRoZSBjZW50cmFsaXR5IG1lYXN1cmVzIG9mIHRoZSBuZXR3b3JrCiMgZGVncmVlOnRoZSBudW1iZXIgb2YgaXRzIGFkamFjZW50IGVkZ2VzIChtZWFzdXJlIG9mIGRpcmVjdCBpbmZsdWVuY2UpCmRlZ19zIDwtIGRlZ3JlZShiaWdyYW1zLm5ldHdvcmtfcywgbW9kZSA9ICJhbGwiKQoKI0stY29yZSBkZWNvbXBvc2l0aW9uIGFsbG93cyB1cyB0byBpZGVudGlmeSB0aGUgY29yZSBhbmQgdGhlIHBlcmlwaGVyeSBvZiB0aGUgbmV0d29yay4gQSBrLWNvcmUgaXMgYSBtYXhpbWFsIHN1Ym5ldCBvZiBhIG5ldHdvcmsgc3VjaCB0aGF0IGFsbCBub2RlcyBoYXZlIGF0IGxlYXN0IGRlZ3JlZSBLLgpjb3JlX3MgPC0gY29yZW5lc3MoYmlncmFtcy5uZXR3b3JrX3MsIG1vZGUgPSAiYWxsIikKCiMgYmV0d2Vlbm5lc3MgbWVhc3VyZXMgYnJva2VyYWdlIG9yIGdhdGVrZWVwaW5nIHBvdGVudGlhbC4gSXQgaXMgKGFwcHJveGltYXRlbHkpIHRoZSBudW1iZXIgb2Ygc2hvcnRlc3QgcGF0aHMgYmV0d2VlbiBub2RlcyB0aGF0IHBhc3MgdGhyb3VnaCBhIHBhcnRpY3VsYXIgbm9kZS4KYmV0d19zIDwtIGJldHdlZW5uZXNzKGJpZ3JhbXMubmV0d29ya19zKQoKI0VpZ2VudmVjdG9yIGNlbnRyYWxpdHkgaXMgYSBtZWFzdXJlIG9mIGJlaW5nIHdlbGwtY29ubmVjdGVkIGNvbm5lY3RlZCB0byB0aGUgd2VsbC1jb25uZWN0ZWQuIEZpcnN0IGVpZ2VudmVjdG9yIG9mIHRoZSBncmFwaCBhZGphY2VuY3kgbWF0cml4LiBPbmx5IHdvcmtzIHdpdGggdW5kaXJlY3RlZCBuZXR3b3Jrcy4KZWlnZW5fcyA8LSBlaWdlbl9jZW50cmFsaXR5KGJpZ3JhbXMubmV0d29ya19zLCBkaXJlY3RlZCA9IFRSVUUpCm1lbWJlcnNfcyA8LSBjbHVzdGVyX3dhbGt0cmFwKGJpZ3JhbXMubmV0d29ya19zKQoKbGlicmFyeShpZ3JhcGgpCmJpZ3JhbXMubmV0d29ya19zIDwtIHNpbXBsaWZ5KGJpZ3JhbXMubmV0d29ya19zCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjcmVtb3ZlLm11bHRpcGxlID0gRkFMU0UsICNlcnJvciBvY2N1cmVkID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICNyZW1vdmUubG9vcHMgPSBUUlVFKQopClYoYmlncmFtcy5uZXR3b3JrX3MpJGNvbG9yIDwtIG1lbWJlcnNfcyRtZW1iZXJzaGlwKzEKCiMgVXNpbmcgIkNvcmVuZXNzIiBhcyBzaXplCiMgQ29yZW5lc3MgLT4gbWVhbiAoYXZlcmFnZSBkaXN0YW5jZSB0byBhbGwgdGhlIG90aGVyIG5vZGVzLCBkaWZmdXNpb24gb2YgaW5mb3JtYXRpb24pCnBsb3QoYmlncmFtcy5uZXR3b3JrX3MsCiAgICAgbGF5b3V0ID0gbGF5b3V0X3dpdGhfZnIsCiAgICAgdmVydGV4LmxhYmVsLmNvbG9yID0gImJsYWNrIiwKICAgICB2ZXJ0ZXgubGFiZWwuY2V4ID0gMC45LAogICAgIHZlcnRleC5sYWJlbC5kaXN0ID0gMCwKICAgICB2ZXJ0ZXguZnJhbWUuY29sb3IgPSAwLAogICAgIHZlcnRleC5zaXplID0gY29yZV9zKjEwLCAKICAgICBlZGdlLmFycm93LnNpemUgPSAwLjAxLAogICAgIGVkZ2UuY3VydmVkID0gMC43LAogICAgIGVkZ2UuY29sb3IgPSAiZ3JheSIsCiAgICAgbWFpbiA9ICJCaWdyYW0gQ29tbXVuaXRpZXMgKFNhbXN1bmcpIgopCm10ZXh0KCJDb3JlbmVzcyIpCgojIFVzaW5nICJEZWdyZWUiIGFzIHNpemUKIyBkZWdyZWU9bW9kZSAobnVtYmVyIG9mIGVkZ2VzIG9mIHRoZSBub2RlLCBpbi1kZWdyZWU6cHJlc3RpZ2UKCnBsb3QoYmlncmFtcy5uZXR3b3JrX3MsCiAgICAgbGF5b3V0ID0gbGF5b3V0X3dpdGhfZnIsCiAgICAgdmVydGV4LmxhYmVsLmNvbG9yID0gImJsYWNrIiwKICAgICB2ZXJ0ZXgubGFiZWwuY2V4ID0gMC45LAogICAgIHZlcnRleC5sYWJlbC5kaXN0ID0gMCwKICAgICB2ZXJ0ZXguZnJhbWUuY29sb3IgPSAwLAogICAgIHZlcnRleC5zaXplID0gZGVnX3MsIAogICAgIGVkZ2UuYXJyb3cuc2l6ZSA9IDAuMDEsCiAgICAgZWRnZS5jdXJ2ZWQgPSAwLjcsCiAgICAgZWRnZS5jb2xvciA9ICJncmF5IiwKICAgICBtYWluID0gIkJpZ3JhbSBDb21tdW5pdGllcyAoU2Ftc3VuZykiCikKbXRleHQoIkRlZ3JlZSIpCgojIFVzaW5nICJFaWdlbnZlY3RvciBDZW50cmFsaXR5IiBhcyBzaXplCiMgY2VudHJhbGl0eSAodGhlIG1vc3QgY29ubmVjdGVkIHdvcmRzKQpwbG90KGJpZ3JhbXMubmV0d29ya19zLAogICAgIGxheW91dCA9IGxheW91dF93aXRoX2ZyLAogICAgIHZlcnRleC5sYWJlbC5jb2xvciA9ICJibGFjayIsCiAgICAgdmVydGV4LmxhYmVsLmNleCA9IDAuOCwKICAgICB2ZXJ0ZXgubGFiZWwuZGlzdCA9IDAsCiAgICAgdmVydGV4LnNpemUgPSBlaWdlbl9zJHZlY3RvcioyMCwgCiAgICAgZWRnZS5hcnJvdy5zaXplID0gMC4wMSwKICAgICBlZGdlLmN1cnZlZCA9IDAuNywKICAgICBlZGdlLmNvbG9yID0gImJsYWNrIiwKICAgICBtYWluID0gIkJpZ3JhbSBDb21tdW5pdGllcyAoU2Ftc3VuZykiCikKbXRleHQoIkVpZ2VudmVjdG9yIENlbnRyYWxpdHkiKQoKIyBVc2luZyAiQmV0d2Vlbm5lc3MiIGFzIHNpemUKI0JldHdlZW5uZXNzIC0+IG1lZGlhbiAod2VpZ2h0ZWQgIyBvZiBwYXRocyBnb2luZyB0aHJvdWdoIHRoZSBub2RlKQpwbG90KGJpZ3JhbXMubmV0d29ya19zLAogICAgIGxheW91dCA9IGxheW91dF93aXRoX2ZyLAogICAgIHZlcnRleC5sYWJlbC5jb2xvciA9ICJibGFjayIsCiAgICAgdmVydGV4LmxhYmVsLmNleCA9IDAuOCwKICAgICB2ZXJ0ZXgubGFiZWwuZGlzdCA9IDAsCiAgICAgdmVydGV4LnNpemUgPSBiZXR3X3MsIAogICAgIGVkZ2UuYXJyb3cuc2l6ZSA9IDAuMDEsCiAgICAgZWRnZS5jdXJ2ZWQgPSAwLjcsCiAgICAgZWRnZS5jb2xvciA9ICJsaWdodGdyZXkiLAogICAgIG1haW4gPSAiQmlncmFtIENvbW11bml0aWVzIChTYW1zdW5nKSIKKQptdGV4dCgiQmV0d2Vlbm5lc3MiKQoKYGBgCgpgYGB7ciBOZXR3b3JrIGZvciBBcHBsZSwgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIG5vdyB3ZSBmaW5kIHRoZSBjZW50cmFsaXR5IG1lYXN1cmVzIG9mIHRoZSBuZXR3b3JrCiMgZGVncmVlOnRoZSBudW1iZXIgb2YgaXRzIGFkamFjZW50IGVkZ2VzIChtZWFzdXJlIG9mIGRpcmVjdCBpbmZsdWVuY2UpCmRlZ19hIDwtIGRlZ3JlZShiaWdyYW1zLm5ldHdvcmtfYSwgbW9kZSA9ICJhbGwiKQoKI0stY29yZSBkZWNvbXBvc2l0aW9uIGFsbG93cyB1cyB0byBpZGVudGlmeSB0aGUgY29yZSBhbmQgdGhlIHBlcmlwaGVyeSBvZiB0aGUgbmV0d29yay4gQSBrLWNvcmUgaXMgYSBtYXhpbWFsIHN1Ym5ldCBvZiBhIG5ldHdvcmsgc3VjaCB0aGF0IGFsbCBub2RlcyBoYXZlIGF0IGxlYXN0IGRlZ3JlZSBLLgpjb3JlX2EgPC0gY29yZW5lc3MoYmlncmFtcy5uZXR3b3JrX2EsIG1vZGUgPSAiYWxsIikKCiMgYmV0d2Vlbm5lc3MgbWVhc3VyZXMgYnJva2VyYWdlIG9yIGdhdGVrZWVwaW5nIHBvdGVudGlhbC4gSXQgaXMgKGFwcHJveGltYXRlbHkpIHRoZSBudW1iZXIgb2Ygc2hvcnRlc3QgcGF0aHMgYmV0d2VlbiBub2RlcyB0aGF0IHBhc3MgdGhyb3VnaCBhIHBhcnRpY3VsYXIgbm9kZS4KYmV0d19hIDwtIGJldHdlZW5uZXNzKGJpZ3JhbXMubmV0d29ya19hKQoKI0VpZ2VudmVjdG9yIGNlbnRyYWxpdHkgaXMgYSBtZWFzdXJlIG9mIGJlaW5nIHdlbGwtY29ubmVjdGVkIGNvbm5lY3RlZCB0byB0aGUgd2VsbC1jb25uZWN0ZWQuIEZpcnN0IGVpZ2VudmVjdG9yIG9mIHRoZSBncmFwaCBhZGphY2VuY3kgbWF0cml4LiBPbmx5IHdvcmtzIHdpdGggdW5kaXJlY3RlZCBuZXR3b3Jrcy4KZWlnZW5fYSA8LSBlaWdlbl9jZW50cmFsaXR5KGJpZ3JhbXMubmV0d29ya19hLCBkaXJlY3RlZCA9IFRSVUUpCm1lbWJlcnNfYSA8LSBjbHVzdGVyX3dhbGt0cmFwKGJpZ3JhbXMubmV0d29ya19hKQoKbGlicmFyeShpZ3JhcGgpCmJpZ3JhbXMubmV0d29ya19hIDwtIHNpbXBsaWZ5KGJpZ3JhbXMubmV0d29ya19hCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjcmVtb3ZlLm11bHRpcGxlID0gRkFMU0UsICNlcnJvciBvY2N1cmVkID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICNyZW1vdmUubG9vcHMgPSBUUlVFKQopClYoYmlncmFtcy5uZXR3b3JrX2EpJGNvbG9yIDwtIG1lbWJlcnNfYSRtZW1iZXJzaGlwKzEKCiMgVXNpbmcgIkNvcmVuZXNzIiBhcyBzaXplCiMgQ29yZW5lc3MgLT4gbWVhbiAoYXZlcmFnZSBkaXN0YW5jZSB0byBhbGwgdGhlIG90aGVyIG5vZGVzLCBkaWZmdXNpb24gb2YgaW5mb3JtYXRpb24pCnBsb3QoYmlncmFtcy5uZXR3b3JrX2EsCiAgICAgbGF5b3V0ID0gbGF5b3V0X3dpdGhfZnIsCiAgICAgdmVydGV4LmxhYmVsLmNvbG9yID0gImJsYWNrIiwKICAgICB2ZXJ0ZXgubGFiZWwuY2V4ID0gMC45LAogICAgIHZlcnRleC5sYWJlbC5kaXN0ID0gMCwKICAgICB2ZXJ0ZXguZnJhbWUuY29sb3IgPSAwLAogICAgIHZlcnRleC5zaXplID0gY29yZV9hKjEwLCAKICAgICBlZGdlLmFycm93LnNpemUgPSAwLjAxLAogICAgIGVkZ2UuY3VydmVkID0gMC43LAogICAgIGVkZ2UuY29sb3IgPSAiZ3JheSIsCiAgICAgbWFpbiA9ICJCaWdyYW0gQ29tbXVuaXRpZXMgKGlQaG9uZSAxMykiCikKbXRleHQoIkNvcmVuZXNzIikKCiMgVXNpbmcgIkRlZ3JlZSIgYXMgc2l6ZQojIGRlZ3JlZT1tb2RlIChudW1iZXIgb2YgZWRnZXMgb2YgdGhlIG5vZGUsIGluLWRlZ3JlZTpwcmVzdGlnZQoKcGxvdChiaWdyYW1zLm5ldHdvcmtfYSwKICAgICBsYXlvdXQgPSBsYXlvdXRfd2l0aF9mciwKICAgICB2ZXJ0ZXgubGFiZWwuY29sb3IgPSAiYmxhY2siLAogICAgIHZlcnRleC5sYWJlbC5jZXggPSAwLjksCiAgICAgdmVydGV4LmxhYmVsLmRpc3QgPSAwLAogICAgIHZlcnRleC5mcmFtZS5jb2xvciA9IDAsCiAgICAgdmVydGV4LnNpemUgPSBkZWdfYSwgCiAgICAgZWRnZS5hcnJvdy5zaXplID0gMC4wMSwKICAgICBlZGdlLmN1cnZlZCA9IDAuNywKICAgICBlZGdlLmNvbG9yID0gImdyYXkiLAogICAgIG1haW4gPSAiQmlncmFtIENvbW11bml0aWVzIChpUGhvbmUgMTMpIgopCm10ZXh0KCJEZWdyZWUiKQoKIyBVc2luZyAiRWlnZW52ZWN0b3IgQ2VudHJhbGl0eSIgYXMgc2l6ZQojIGNlbnRyYWxpdHkgKHRoZSBtb3N0IGNvbm5lY3RlZCB3b3JkcykKcGxvdChiaWdyYW1zLm5ldHdvcmtfYSwKICAgICBsYXlvdXQgPSBsYXlvdXRfd2l0aF9mciwKICAgICB2ZXJ0ZXgubGFiZWwuY29sb3IgPSAiYmxhY2siLAogICAgIHZlcnRleC5sYWJlbC5jZXggPSAwLjgsCiAgICAgdmVydGV4LmxhYmVsLmRpc3QgPSAwLAogICAgIHZlcnRleC5zaXplID0gZWlnZW5fYSR2ZWN0b3IqMjAsIAogICAgIGVkZ2UuYXJyb3cuc2l6ZSA9IDAuMDEsCiAgICAgZWRnZS5jdXJ2ZWQgPSAwLjcsCiAgICAgZWRnZS5jb2xvciA9ICJibGFjayIsCiAgICAgbWFpbiA9ICJCaWdyYW0gQ29tbXVuaXRpZXMgKGlQaG9uZSAxMykiCikKbXRleHQoIkVpZ2VudmVjdG9yIENlbnRyYWxpdHkiKQoKIyBVc2luZyAiQmV0d2Vlbm5lc3MiIGFzIHNpemUKI0JldHdlZW5uZXNzIC0+IG1lZGlhbiAod2VpZ2h0ZWQgIyBvZiBwYXRocyBnb2luZyB0aHJvdWdoIHRoZSBub2RlKQpwbG90KGJpZ3JhbXMubmV0d29ya19hLAogICAgIGxheW91dCA9IGxheW91dF93aXRoX2ZyLAogICAgIHZlcnRleC5sYWJlbC5jb2xvciA9ICJibGFjayIsCiAgICAgdmVydGV4LmxhYmVsLmNleCA9IDAuOCwKICAgICB2ZXJ0ZXgubGFiZWwuZGlzdCA9IDAsCiAgICAgdmVydGV4LnNpemUgPSBiZXR3X2EsIAogICAgIGVkZ2UuYXJyb3cuc2l6ZSA9IDAuMDEsCiAgICAgZWRnZS5jdXJ2ZWQgPSAwLjcsCiAgICAgZWRnZS5jb2xvciA9ICJsaWdodGdyZXkiLAogICAgIG1haW4gPSAiQmlncmFtIENvbW11bml0aWVzIChpUGhvbmUgMTMpIgopCm10ZXh0KCJCZXR3ZWVubmVzcyIpCgpgYGAK